Reputation: 1351
I have an .NET 4.0 application using Caliburn.Micro. I want to create a dynamic menu such that I don't need to write XAML code for each menu item. Additionally, I want to associate each command with a key gesture.
I have an interface IAction:
public interface IAction
{
string Name { get; }
InputGesture Gesture { get; }
ICommand Command { get; }
}
In my ViewModel I expose a list of IActions:
private List<IAction> _actions;
public List<IAction> Actions
{
get { return _actions; }
set
{
_actions = value;
NotifyOfPropertyChange(()=> Actions);
}
}
I bind my Toolbar to the actions as follows:
<ToolBar>
<Menu ItemsSource="{Binding Actions}">
<Menu.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="Header" Value="{Binding Name}" />
<Setter Property="Command" Value="{Binding Command}" />
</Style>
</Menu.ItemContainerStyle>
</Menu>
</ToolBar>
All of the above works.
What I'm missing is the databinding of the Key Gesture.
Everywhere I read, I only find examples with static definitions of Window.InputBindings such as:
<Window.InputBindings>
<KeyBinding Key="B" Modifiers="Control" Command="ApplicationCommands.Open" />
</Window.InputBindings>
It would be great if I simply could encapsulate the Window.InputBindings in an ItemsControl, but that doesn't work.
Any of you know how to dynamically bind Window.InputBindings?
Thanks!
Upvotes: 1
Views: 1024
Reputation: 17272
Key gestures have to be created for the window object (if they are to have window-wide effect).
I guess you could create a custom derived window object which would have a dependency property named for example BindableInputBindings
. This property in its OnChanged callback would add/remove the key bindings every time the source collection changed.
EDIT: There may be some errors.
public class WindowWithBindableKeys: Window {
protected static readonly DependencyProperty BindableKeyBindingsProperty = DependencyProperty.Register(
"BindableKeyBindings", typeof(CollectionOfYourKeyDefinitions), typeof(WindowWithBindableKeys), new FrameworkPropertyMetadata("", new PropertyChangedCallback(OnBindableKeyBindingsChanged))
);
public CollectionOfYourKeyDefinitions BindableKeyBindings
{
get
{
return (string)GetValue(BindableKeyBindingsProperty);
}
set
{
SetValue(BindableKeyBindingsProperty, value);
}
}
private static void OnBindableKeyBindingsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as WindowWithBindableKeys).InputBindings.Clear();
// add the input bidnings according to the BindableKeyBindings
}
}
Then in XAML
<mynamespace:WindowWithBindableKeys BindableKeyBindings={Binding YourSourceOfKeyBindings} ... > ...
Upvotes: 2