In my XAML I have this:
<UserControl.CommandBindings>
<CommandBinding Command="Help"
CanExecute="HelpCanExecute"
Executed="HelpExecuted" />
</UserControl.CommandBindings>
<MenuItem Header="Help" Command="Help" />
This works fine. So when I click the context menu, HelpExecuted() gets called.
Now I want to do the same again except use a custom command instead of the Help command. So what I do is:
public RoutedCommand MyCustomCommand = new RoutedCommand();
and change my XAML to:
<UserControl.CommandBindings>
<CommandBinding Command="MyCustomCommand"
CanExecute="HelpCanExecute"
Executed="HelpExecuted" />
</UserControl.CommandBindings>
<MenuItem Header="Help" Command="MyCustomCommand" />
But i get the error: Cannot convert string 'MyCustomCommand' in attribute 'Command' to object of type 'System.Windows.Input.ICommand'. CommandConverter cannot convert from System.String.
What am I missing here? And please note that I want to do it all in XAML, i.e. don't want to use CommandBindings.Add(new CommandBinding(MyCustomCommand....
Oops, sorry, was a bit fast to post my original answer. I now see that the problem is not with the type but with the CommandBinding. You need to use a markup extension to resolve the command name. I usually make my commands static in their declaration like this:
namespace MyApp.Commands
{
public class MyApplicationCommands
{
public static RoutedUICommand MyCustomCommand
= new RoutedUICommand("My custom command",
"MyCustomCommand",
typeof(MyApplicationCommands));
}
}
And in the XAML:
<UserControl x:Class="..."
...
xmlns:commands="clr-namespace:MyApp.Commands">
...
<UserControl.CommandBindings>
<CommandBinding Command="{x:Static commands:MyApplicationCommands.MyCustomCommand}"
CanExecute="HelpCanExecute"
Executed="HelpExecuted" />
</UserControl.CommandBindings>
You need to bring in the namespace of the containing class by using xmlns. I called it 'commands' in my example above.
Original post below:
Try changing the type of the command to RoutedUICommand. The constructor is a bit different:
public RoutedUICommand MyCustomCommand
= new RoutedUICommand("Description", "Name", typeof(ContainingClass));
Related
I checked a lot of of answers here about shortcuts bindings, but did not find the simple way to execute some method from the C# code.
First, in the following classic example I don't understand what actually we are binding. What the meaning of Command attribute? What is the ApplicationCommands? Where is ApplicationCommands.Open has been declared?
<Window.InputBindings>
<KeyBinding Command="ApplicationCommands.Open"
Gesture="CTRL+R" />
</Window.InputBindings>
In the one of answer of question similar to my one, "XAML is the markup language, so we could not call the method from there" has been told. OK, in this case, WHY we can call the method OnClickBtn1 from the code below?
<Button
x:Name="SomeButton"
Click="OnClickBtn1"/>
Finally, my problem. All I need is to execute OnClickBtn1 method by Ctrl+H (for example) shortcut same as effect when the button Btn1 clicked. I understand that following code is not enough.
XAML:
<Window x:Name="MainDisplay"
<!-- ... --->
>
<Window.InputBindings>
<KeyBinding Gesture="Ctrl+H" Command="{Binding OnClickBtn1}" />
</Window.InputBindings>
<!-- ... -->
<Button x:Name="Btn1"
Width="70"
Content="Button"
Click="OnClickBtn1"/>
C#:
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
}
private void OnClickBtn1(object sender, RoutedEventArgs e) {
System.Diagnostics.Debug.WriteLine("Btn1 has been clicked or Ctrl+H had been inputed");
}
}
In all examples that I checked, first two arguments of RoutedUICommand() are same string, e.g.
private static RoutedUICommand add = new RoutedUICommand("Add", "Add", typeof(CommandLibrary));
What the difference between them?
You can always check the metadata for the meaning by pressing F12 with your I-beam on the class while using Visual Studio.
Anyway, with the constructor RoutedUICommand(String, String, Type): the first string is a descriptive text, the second is the name, and the third is the owner type. It doesn't have to be the same.
Consider this example here:
public static RoutedCommand GreetUserCommand = new RoutedUICommand("Howdy! Just to say hello, nothing else.", "GreetUser", typeof(MainWindow));
and usage of the view:
<Window.CommandBindings>
<CommandBinding Command="{x:Static loc:MainWindow.GreetUserCommand}"
CanExecute="GreetUser_CanExecute" Executed="GreetUser_Executed"/>
</Window.CommandBindings>
<Window.ContextMenu>
<ContextMenu>
<MenuItem Command="{x:Static loc:MainWindow.GreetUserCommand}"/>
</ContextMenu>
</Window.ContextMenu>
I have strange error in WPF using .NET Framework 4.5
<Window.CommandBindings>
<CommandBinding Command="ImportExcelCmd" CanExecute="ImportExcelCmd_CanExecute" Executed="ImportExcelCmd_Executed"></CommandBinding>
</Window.CommandBindings>
<Window.InputBindings>
<KeyBinding Key="I" Modifiers="Control" Command="ImportExcelCmd"></KeyBinding>
</Window.InputBindings>
I receive an error that CommandConverter cannot convert from System.String
Where is my mistake ?
I have another binding to a ListView, like:
<ListView.CommandBindings>
<CommandBinding Command="Delete" CanExecute="Delete_CanExecute" Executed="Delete_Executed"></CommandBinding>
</ListView.CommandBindings>
<ListView.InputBindings>
<KeyBinding Key="Delete" Command="Delete"></KeyBinding>
</ListView.InputBindings>
and it works.
If you want to use Custom Routed commands, you to use more verbose definition.
Declare the routed command as static in class and then use it in XAML using x:Static.
You can refer to the answer here.
For the sake of completeness of the answer, I am posting the relevant code from the answer here:
namespace MyApp.Commands
{
public class MyApplicationCommands
{
public static RoutedUICommand ImportExcelCmd
= new RoutedUICommand("Import excel command",
"ImportExcelCmd",
typeof(MyApplicationCommands));
}
}
XAML
<Window x:Class="..."
...
xmlns:commands="clr-namespace:MyApp.Commands">
...
<Window.CommandBindings>
<CommandBinding
Command="{x:Static commands:MyApplicationCommands.ImportExcelCmd}"
CanExecute="ImportExcelCmd_CanExecute"
Executed="ImportExcelCmd_Executed" />
</Window.CommandBindings>
Within my window (let's say MyCanvas) there's a new command definition which I then bind to my window. Usually the handlers for CanExecute and Executed are directly within MyCanvas. But is it somehow possible to bind the CanExecute and Executed handlers to a relative path like for example MyCanvas.Logic.CanExecute_OpenCamera?
This is my current XAML.
<Window.Resources>
<RoutedUICommand x:Key="OpenCamera" Text="Open camera" />
</Window.Resources>
<Window.CommandBindings>
<CommandBinding Command="{StaticResource OpenCamera}" CanExecute="CanExecute_OpenCamera" Executed="Executed_OpenCamera"/>
</Window.CommandBindings>
This is what I'm trying to define. Logic is public property of MyCanvas.
<Window.Resources>
<RoutedUICommand x:Key="OpenCamera" Text="Open camera" />
</Window.Resources>
<Window.CommandBindings>
<CommandBinding Command="{StaticResource OpenCamera}" CanExecute="Logic.CanExecute_OpenCamera" Executed="Logic.Executed_OpenCamera"/>
</Window.CommandBindings>
You can, but you have to use converters which create delegates to the respective methods from a bound object of the class, or from its type, if the methods are static. See http://wpfglue.wordpress.com/2012/05/07/commanding-binding-controls-to-methods/ for details.
I am working with WPF. I want to create keyboard shortcuts for my WPF application. I have created as following. The first command binding tag for "open" is working and command binding for exit is not working. I dont know what is the reason.
<Window.CommandBindings>
<CommandBinding Command="Open" Executed="CommandBinding_Executed"/>
<CommandBinding Command="Exit" Executed="CommandBinding_Executed_1" />
</Window.CommandBindings>
<Window.InputBindings>
<KeyBinding Command="Open" Key="O" Modifiers="control" />
<KeyBinding Command="Exit" Key="E" Modifiers="control"/>
</Window.InputBindings>
Above code is getting the following error:
Cannot convert string 'Exit' in attribute 'Command' to object of type
'System.Windows.Input.ICommand'. CommandConverter cannot convert from
System.String. Error at object 'System.Windows.Input.CommandBinding' in
markup file 'WpfApplication2;component/window1.xaml' Line 80 Position 25.
You problem is that there is no exit command. You'll have to roll your own.
See here for built-in ApplicationCommands
It's pretty easy to create your own, I use a static utility class to hold common commands that I use often. Something like this:
public static class AppCommands
{
private static RoutedUICommand exitCommand = new RoutedUICommand("Exit","Exit", typeof(AppCommands));
public static RoutedCommand ExitCommand
{
get { return exitCommand; }
}
static AppCommands()
{
CommandBinding exitBinding = new CommandBinding(exitCommand);
CommandManager.RegisterClassCommandBinding(typeof(AppCommands), exitBinding);
}
}
Then you should be able to bind it like this:
<KeyBinding Command="{x:Static local:AppCommands.Exit}" Key="E" Modifiers="control"/>