Динамическое меню с ключевыми жестами - PullRequest
1 голос
/ 16 февраля 2011

У меня есть приложение .NET 4.0, использующее Caliburn.Micro.Я хочу создать динамическое меню таким образом, чтобы мне не нужно было писать код XAML для каждого пункта меню.Кроме того, я хочу связать каждую команду с жестом клавиши.

У меня есть интерфейс IAction:

public interface IAction
{
    string Name { get; }
    InputGesture Gesture { get; }
    ICommand Command { get; }      
}

В моей ViewModel я представляю список IActions:

private List<IAction> _actions;
public List<IAction> Actions
{
    get { return _actions; }
    set
    {
        _actions = value;
        NotifyOfPropertyChange(()=> Actions);
    }
}

Я привязываю свою панель инструментов к следующим действиям:

<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>

Все вышеперечисленные работы.

Что мне не хватает, так это привязке данных Жеста ключа.

Везде, где я читаю, я нахожу только примеры со статическими определениями Window.InputBindings, такими как:

<Window.InputBindings>
  <KeyBinding Key="B" Modifiers="Control" Command="ApplicationCommands.Open" />
</Window.InputBindings>

Было бы здорово, если бы я просто мог инкапсулировать Window.InputBindings в ItemsControl, но это нене работает.

Кто-нибудь из вас знает, как динамически связывать Window.InputBindings?

Спасибо!

1 Ответ

2 голосов
/ 16 февраля 2011

Ключевые жесты должны быть созданы для объекта окна (если они должны иметь эффект всего окна).

Полагаю, вы могли бы создать собственный производный объект окна, у которого было бы свойство зависимости, названное, например, BindableInputBindings.Это свойство в обратном вызове OnChanged будет добавлять / удалять привязки клавиш при каждом изменении исходной коллекции.

РЕДАКТИРОВАТЬ: могут быть некоторые ошибки.

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
    }

}

Затем в XAML

<mynamespace:WindowWithBindableKeys BindableKeyBindings={Binding YourSourceOfKeyBindings} ... > ...
...