-1

How should I go about adding KeyBinding commands programmatically based on a string? In my xaml code I have properties like the following one.

<KeyBinding Key="Q" Command="{Binding AcceptAndNextCommand}" />

This works fine but I would like to be able to add this kind of key bindings dynamically and so I want to be able to add them programmatically. I have created a project settings file where each of my KeyBindings is a separate row. This row possesses over a dictionary value where I have saved each keyboard key as a dictionary key and each command as a dictionary value; e.g.: {"Key":"Q", "Value":"AcceptAndNextCommand"}. A String to KeyBinding Key conversion works fine but I'm not sure how to add a Command to the KeyBinding based on a String. All the command strings in the dictionary value look like this "AcceptAndNextCommand". I was hoping that I could make this work with a CommandConverter cv as in my example below but that does not seem to work.

private void KeyboardShortcuts()
    {
        foreach (SettingsProperty property in Properties.KeyboardBindings.Default.Properties)
        {
            var propertyValue = JsonConvert.DeserializeObject<Dictionary<string, string>>(
                Properties.KeyboardBindings.Default[property.Name].ToString());

            var keyBinding = new KeyBinding()
            {
                Key = (Key)new KeyConverter().ConvertFromString(propertyValue["Key"])
            };

            CommandConverter cv = TypeDescriptor.GetConverter(typeof(ICommand)) as CommandConverter;
            keyBinding.Command = (ICommand)cv?.ConvertFromString(propertyValue["Command"]);
        }
    }

I based my implementation on the following question but it did not explain the addition of commands very well.

mm8
  • 163,881
  • 10
  • 57
  • 88
Adrian Z.
  • 904
  • 1
  • 12
  • 29

1 Answers1

1

You could use the BindingOperations.SetBinding method to programmatically create a binding:

KeyBinding kb = new KeyBinding();
BindingOperations.SetBinding(kb, KeyBinding.CommandProperty, new Binding("AcceptAndNextCommand"));
...
InputBindings.Add(kb);

The path of a binding is just a string.

mm8
  • 163,881
  • 10
  • 57
  • 88
  • This does not set a keybinding in the view does it? I just ran it and it did not throw any errors but also nothing at all happened. – Adrian Z. Dec 20 '17 at 15:34
  • In the view? It sets the command of the KeyBinding that you pass to the SetBinding method...Of course you need to add the KeyBinding that you are creating programmatically to the view somehow. Or where else do you plan to use the KeyBinding? – mm8 Dec 20 '17 at 15:35
  • That is what I meant with my comment. How do I add it then to the view in which the keybinding should be used? – Adrian Z. Dec 20 '17 at 15:41
  • It's in the code behind a UserControl used as the main View. – Adrian Z. Dec 20 '17 at 15:44
  • You say in your question that "In my xaml code I have properties like the following one...". Do these work? *Where* do you define them? – mm8 Dec 20 '17 at 15:45
  • Yes, they work but now I'm trying to do exactly the same as in the xaml file but in its code behind. The xaml properties are define in ``. I'm not exactly sure what you mean with `where`. – Adrian Z. Dec 20 '17 at 15:48
  • 1
    Just add the KeyBinding that you create programmatically to the InputBindings collection then: this.InputBindings.Add(kb); – mm8 Dec 20 '17 at 15:49
  • Then you are obviously doing something wrong. Try to hardcode the string values. And please provide a full repo of your issue if you want anyone to be able to help you any further. – mm8 Dec 20 '17 at 15:53
  • If I try to print the command in the keybinding I get a null reference. This could be the reason. – Adrian Z. Dec 20 '17 at 15:57
  • The BindingOperations seem to be doing nothing on the KeyBinding. – Adrian Z. Dec 20 '17 at 16:02
  • Do you have a DataContext with an AcceptAndNextCommand property? – mm8 Dec 20 '17 at 16:05
  • Yes, I do have AcceptAndNextCommand in my DataContext but does that matter for BindingOperations? I'm checking if everything gets set by just simply debugging and the only value that does not get set is the `Command` of my `keyBinding` variable. – Adrian Z. Dec 20 '17 at 16:08
  • Then you are doing something wrong. The binding should work. I've verified that this works. Of course you will have to wait to check the property until the binding has been resolved though. – mm8 Dec 20 '17 at 16:10
  • I'm sure that I'm doing something wrong but what do you exactly mean with that I have to wait? – Adrian Z. Dec 20 '17 at 16:12
  • Again, please provide a repo of your issue if you still cannot get this to work: https://stackoverflow.com/help/mcve – mm8 Dec 20 '17 at 16:13