<Button Margin="5" Command="local:DataCommands.Requery">Requery</Button>
public partial class CustomCommand : System.Windows.Window
{
public CustomCommand()
{
InitializeComponent();
}
private void RequeryCommand(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("Requery");
}
}
public class DataCommands
{
private static RoutedUICommand requery;
static DataCommands()
{
InputGestureCollection inputs = new InputGestureCollection();
inputs.Add(new KeyGesture(Key.R, ModifierKeys.Control, "Ctrl+R"));
requery = new RoutedUICommand(
"Requery", "Requery", typeof(DataCommands), inputs);
}
public static RoutedUICommand Requery
{
get { return requery; }
}
}
<Window.Resources>
<local:FontStringValueConverter x:Key="StringConverterResource"/>
<local:FontDoubleValueConverter x:Key="DoubleConverterResource"/>
</Window.Resources>
<StackPanel>
<Border BorderBrush="Black"
BorderThickness="2"
Margin="10"
Width="400"
Height="400">
<StackPanel>
<StackPanel Margin="10">
<Label HorizontalAlignment="Center">
Custom Slider that Invokes a Command
</Label>
<Border Width="350" Background="LightBlue">
<local:CommandSlider x:Name="FontSlider"
Background="AliceBlue"
Minimum="0"
Maximum="60"
Value="12"
TickFrequency="5"
Height="50"
Width="275"
TickPlacement="BottomRight"
LargeChange="5"
SmallChange="5"
AutoToolTipPlacement="BottomRight"
AutoToolTipPrecision="0"
Command="{x:Static local:CustomControlWithCommand.FontUpdateCommand}"
CommandTarget="{Binding ElementName=txtBoxTarget}"
CommandParameter="{Binding ElementName=FontSlider,
Path=Value,
Converter={StaticResource DoubleConverterResource}}"
Focusable="False"/>
</Border>
</StackPanel>
<Border BorderBrush="Black"
BorderThickness="1"
Height="150"
Width="300"
Margin="15">
<StackPanel Margin="5">
<CheckBox IsChecked="False"
Checked="OnReadOnlyChecked"
Unchecked="OnReadOnlyUnChecked"
Content="Read Only"
Margin="5"
FontSize="12" />
<TextBox Name="txtBoxTarget" Height="100" Width="275" Margin="3">
<TextBox.CommandBindings>
<CommandBinding Command="{x:Static local:CustomControlWithCommand.FontUpdateCommand}"
Executed="SliderUpdateExecuted"
CanExecute="SliderUpdateCanExecute" />
</TextBox.CommandBindings>
Hello
</TextBox>
</StackPanel>
</Border>
<StackPanel>
<Label HorizontalAlignment="Center">
More Command Sources for the Font Update Command
</Label>
<StackPanel Margin="10" HorizontalAlignment="Left" Background="LightBlue">
<Button Command="{x:Static local:CustomControlWithCommand.FontUpdateCommand}"
CommandTarget="{Binding ElementName=txtBoxTarget}"
CommandParameter="{Binding ElementName=txtValue,
Path=Text,
Converter={
StaticResource StringConverterResource}}"
Height="50"
Width="150"
Margin="1">
Update Font Via Command
</Button>
<TextBox Name="txtValue"
MaxLength="2"
Width="25"
Background="AliceBlue"
Margin="0,0,0,3">5</TextBox>
</StackPanel>
</StackPanel>
</StackPanel>
</Border>
</StackPanel>
public partial class CustomControlWithCommand : System.Windows.Window
{
public CustomControlWithCommand()
{
InitializeComponent();
}
public static RoutedCommand FontUpdateCommand = new RoutedCommand();
//The ExecutedRoutedEvent Handler
//if the command target is the TextBox, changes the fontsize to that
//of the value passed in through the Command Parameter
public void SliderUpdateExecuted(object sender, ExecutedRoutedEventArgs e)
{
TextBox source = sender as TextBox;
if (source != null)
{
if (e.Parameter != null)
{
try
{
if ((int)e.Parameter > 0 && (int)e.Parameter <= 60)
{
source.FontSize = (int)e.Parameter;
}
}
catch
{
MessageBox.Show("in Command \n Parameter: " + e.Parameter);
}
}
}
}
//The CanExecuteRoutedEvent Handler
//if the Command Source is a TextBox, then set CanExecute to ture;
//otherwise, set it to false
public void SliderUpdateCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
TextBox source = sender as TextBox;
if (source != null)
{
if (source.IsReadOnly)
{
e.CanExecute = false;
}
else
{
e.CanExecute = true;
}
}
}
//if the Readonly Box is checked, we need to force the CommandManager
//to raise the RequerySuggested event. This will cause the Command Source
//to query the command to see if it can execute or not.
public void OnReadOnlyChecked(object sender, RoutedEventArgs e)
{
if (txtBoxTarget != null)
{
txtBoxTarget.IsReadOnly = true;
CommandManager.InvalidateRequerySuggested();
}
}
//if the Readonly Box is checked, we need to force the CommandManager
//to raise the RequerySuggested event. This will cause the Command Source
//to query the command to see if it can execute or not.
public void OnReadOnlyUnChecked(object sender, RoutedEventArgs e)
{
if (txtBoxTarget != null)
{
txtBoxTarget.IsReadOnly = false;
CommandManager.InvalidateRequerySuggested();
}
}
}
//Converter to convert the Slider value property to an int
[ValueConversion(typeof(double), typeof(int))]
public class FontStringValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string fontSize = (string)value;
int intFont;
try
{
intFont = Int32.Parse(fontSize);
return intFont;
}
catch (FormatException e)
{
return null;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return null;
}
}
//Converter to convert the Slider value property to an int
[ValueConversion(typeof(double), typeof(int))]
public class FontDoubleValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
double fontSize = (double)value;
return (int)fontSize;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return null;
}
}
<Window.CommandBindings>
<CommandBinding Command="local:MonitorCommands.ApplicationUndo"
Executed="ApplicationUndoCommand_Executed"
CanExecute="ApplicationUndoCommand_CanExecute"></CommandBinding>
</Window.CommandBindings>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<ToolBarTray Grid.Row="0">
<ToolBar>
<Button Command="ApplicationCommands.Cut">Cut</Button>
<Button Command="ApplicationCommands.Copy">Copy</Button>
<Button Command="ApplicationCommands.Paste">Paste</Button>
<Button Command="ApplicationCommands.Undo">Undo</Button>
</ToolBar>
<ToolBar>
<Button Command="local:MonitorCommands.ApplicationUndo">Reverse Last Command</Button>
</ToolBar>
</ToolBarTray>
<TextBox Margin="5" Grid.Row="1"
TextWrapping="Wrap" AcceptsReturn="True">
</TextBox>
<TextBox Margin="5" Grid.Row="2"
TextWrapping="Wrap" AcceptsReturn="True">
</TextBox>
<ListBox Grid.Row="3" Name="lstHistory" Margin="5" DisplayMemberPath="CommandName"></ListBox>
</Grid>
public partial class MonitorCommands : System.Windows.Window
{
private static RoutedUICommand applicationUndo;
public static RoutedUICommand ApplicationUndo
{
get { return MonitorCommands.applicationUndo; }
}
static MonitorCommands()
{
applicationUndo = new RoutedUICommand(
"ApplicationUndo", "Application Undo", typeof(MonitorCommands));
}
public MonitorCommands()
{
InitializeComponent();
this.AddHandler(CommandManager.PreviewExecutedEvent,
new ExecutedRoutedEventHandler(CommandExecuted));
}
private void window_Unloaded(object sender, RoutedEventArgs e)
{
this.RemoveHandler(CommandManager.PreviewExecutedEvent,
new ExecutedRoutedEventHandler(CommandExecuted));
}
private void CommandExecuted(object sender, ExecutedRoutedEventArgs e)
{
// Ignore menu button source.
if (e.Source is ICommandSource) return;
// Ignore the ApplicationUndo command.
if (e.Command == MonitorCommands.ApplicationUndo) return;
// Could filter for commands you want to add to the stack
// (for example, not selection events).
TextBox txt = e.Source as TextBox;
if (txt != null)
{
RoutedCommand cmd = (RoutedCommand)e.Command;
CommandHistoryItem historyItem = new CommandHistoryItem(
cmd.Name, txt, "Text", txt.Text);
ListBoxItem item = new ListBoxItem();
item.Content = historyItem;
lstHistory.Items.Add(historyItem);
// CommandManager.InvalidateRequerySuggested();
}
}
private void ApplicationUndoCommand_Executed(object sender, RoutedEventArgs e)
{
CommandHistoryItem historyItem = (CommandHistoryItem)lstHistory.Items[lstHistory.Items.Count - 1];
if (historyItem.CanUndo) historyItem.Undo();
lstHistory.Items.Remove(historyItem);
}
private void ApplicationUndoCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
if (lstHistory == null || lstHistory.Items.Count == 0)
e.CanExecute = false;
else
e.CanExecute = true;
}
}
public class CommandHistoryItem
{
public string CommandName
{
get;
set;
}
public UIElement ElementActedOn
{
get;
set;
}
public string PropertyActedOn
{
get;
set;
}
public object PreviousState
{
get;
set;
}
public CommandHistoryItem(string commandName)
: this(commandName, null, "", null)
{ }
public CommandHistoryItem(string commandName, UIElement elementActedOn,
string propertyActedOn, object previousState)
{
CommandName = commandName;
ElementActedOn = elementActedOn;
PropertyActedOn = propertyActedOn;
PreviousState = previousState;
}
public bool CanUndo
{
get { return (ElementActedOn != null && PropertyActedOn != ""); }
}
public void Undo()
{
Type elementType = ElementActedOn.GetType();
PropertyInfo property = elementType.GetProperty(PropertyActedOn);
property.SetValue(ElementActedOn, PreviousState, null);
}
}
NotCommand:
public NoCommandTextBox()
{
InitializeComponent();
txt.CommandBindings.Add(new CommandBinding(ApplicationCommands.Cut, null, SuppressCommand));
txt.InputBindings.Add(new KeyBinding(ApplicationCommands.NotACommand, Key.C, ModifierKeys.Control));
//txt.ContextMenu = null;
}
private void SuppressCommand(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = false;
e.Handled = true;
}
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Menu Grid.Row="0">
<MenuItem Header="File">
<MenuItem Command="New"></MenuItem>
<MenuItem Command="Open"></MenuItem>
<MenuItem Command="Save"></MenuItem>
<MenuItem Command="SaveAs"></MenuItem>
<Separator></Separator>
<MenuItem Command="Close"></MenuItem>
</MenuItem>
</Menu>
<ToolBarTray Grid.Row="1">
<ToolBar>
<Button Command="New">New</Button>
<Button Command="Open">Open</Button>
<Button Command="Save">Save</Button>
</ToolBar>
<ToolBar>
<Button Command="Cut">Cut</Button>
<Button Command="Copy">Copy</Button>
<Button Command="Paste">Paste</Button>
</ToolBar>
</ToolBarTray>
<TextBox Name="txt" Margin="5" Grid.Row="2"
TextWrapping="Wrap" AcceptsReturn="True"
TextChanged="txt_TextChanged"></TextBox>
</Grid>
public SimpleDocument()
{
InitializeComponent();
// Create bindings.
CommandBinding binding;
binding = new CommandBinding(ApplicationCommands.New);
binding.Executed += NewCommand;
this.CommandBindings.Add(binding);
binding = new CommandBinding(ApplicationCommands.Open);
binding.Executed += OpenCommand;
this.CommandBindings.Add(binding);
binding = new CommandBinding(ApplicationCommands.Save);
binding.Executed += SaveCommand_Executed;
binding.CanExecute += SaveCommand_CanExecute;
this.CommandBindings.Add(binding);
}
private void NewCommand(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("New command triggered with " + e.Source.ToString());
isDirty = false;
}
private void OpenCommand(object sender, ExecutedRoutedEventArgs e)
{
isDirty = false;
}
private void SaveCommand_Executed(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("Save command triggered with " + e.Source.ToString());
isDirty = false;
}
private bool isDirty = false;
private void txt_TextChanged(object sender, RoutedEventArgs e)
{
isDirty = true;
}
private void SaveCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = isDirty;
}
<Window.CommandBindings>
<CommandBinding Command="ApplicationCommands.New"
Executed="NewCommand" />
</Window.CommandBindings>
<StackPanel >
<Menu>
<MenuItem Header="File">
<MenuItem Command="New"></MenuItem>
</MenuItem>
</Menu>
<Button Margin="5" Padding="5" Command="ApplicationCommands.New"
ToolTip="{x:Static ApplicationCommands.New}">New</Button>
<Button Margin="5" Padding="5" Visibility="Hidden" Command="ApplicationCommands.Open">Open (unwired)</Button>
<Button Margin="5" Padding="5" Visibility="Hidden" Click="cmdDoCommand_Click" >DoCommand</Button>
</StackPanel>
public TestNewCommand()
{
//ApplicationCommands.New.Text = "Completely New";
InitializeComponent();
//CommandBinding bindingNew = new CommandBinding(ApplicationCommands.New);
//bindingNew.Executed += NewCommand;
//this.CommandBindings.Add(bindingNew);
}
private void NewCommand(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("New command triggered by " + e.Source.ToString());
}
private void cmdDoCommand_Click(object sender, RoutedEventArgs e)
{
this.CommandBindings[0].Command.Execute(null);
// ApplicationCommands.New.Execute(null, (Button)sender);
}
<Window.Resources>
<CommandBinding x:Key="binding" Command="ApplicationCommands.Save"
Executed="SaveCommand" CanExecute="SaveCommand_CanExecute" />
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Menu Grid.Row="0">
<MenuItem Header="File">
<MenuItem Command="New"></MenuItem>
<MenuItem Command="Open"></MenuItem>
<MenuItem Command="Save"></MenuItem>
<MenuItem Command="SaveAs"></MenuItem>
<Separator></Separator>
<MenuItem Command="Close"></MenuItem>
</MenuItem>
</Menu>
<ToolBarTray Grid.Row="1">
<ToolBar>
<Button Command="New">New</Button>
<Button Command="Open">Open</Button>
<Button Command="Save">Save</Button>
</ToolBar>
<ToolBar>
<Button Command="Cut">Cut</Button>
<Button Command="Copy">Copy</Button>
<Button Command="Paste">Paste</Button>
</ToolBar>
</ToolBarTray>
<TextBox Margin="5" Grid.Row="2"
TextWrapping="Wrap" AcceptsReturn="True"
TextChanged="txt_TextChanged"
>
<TextBox.CommandBindings>
<StaticResource ResourceKey="binding"></StaticResource>
</TextBox.CommandBindings>
</TextBox>
<TextBox Margin="5" Grid.Row="3"
TextWrapping="Wrap" AcceptsReturn="True"
TextChanged="txt_TextChanged">
<TextBox.CommandBindings>
<StaticResource ResourceKey="binding"></StaticResource>
</TextBox.CommandBindings>
<!--
<TextBox.CommandBindings>
<CommandBinding Command="ApplicationCommands.Save"
Executed="SaveCommand" />
</TextBox.CommandBindings>
-->
</TextBox>
</Grid>
private void SaveCommand(object sender, ExecutedRoutedEventArgs e)
{
string text = ((TextBox)sender).Text;
MessageBox.Show("About to save: " + text);
isDirty[sender] = false;
}
private Dictionary<Object, bool> isDirty = new Dictionary<Object, bool>();
private void txt_TextChanged(object sender, RoutedEventArgs e)
{
isDirty[sender] = true;
}
private void SaveCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
if (isDirty.ContainsKey(sender) && isDirty[sender] == true)
{
e.CanExecute = true;
}
else
{
e.CanExecute = false;
}
}
}