Стиль связывания клавиш - PullRequest
1 голос
/ 16 июня 2011

Я использую класс ICommand, похожий на RelayCommand и подобные варианты, но с расширенными свойствами, которые, как правило, идут с командой.В дополнение к настройке таких свойств как части настройки Command, я могу использовать их при связывании.Например,

<UserControl.InputBindings>
    <KeyBinding Command="{Binding SaveCommand}" Key="{Binding SaveCommand.GestureKey}" Modifiers="{Binding SaveCommand.GestureModifier}" />
</UserControl.InputBindings>

Теперь я хотел бы использовать стиль, чтобы воспользоваться этим, что-то вроде приведенного ниже кода.Это не работает, хотя, очевидно, что KeyBinding не имеет DataContext.Можно ли как-нибудь заставить эту привязку работать или что-то похожее на нее?

Приветствия,
Berryl

<Style x:Key="KeyBindingStyle" TargetType="{x:Type KeyBinding}">
    <Setter Property="Command" Value="{Binding Command}" />
    <Setter Property="Gesture" Value="{Binding GestureKey}" />
    <Setter Property="Modifiers" Value="{Binding GestureModifier}" />
</Style>

<UserControl.InputBindings>
    <KeyBinding DataContext="{Binding SaveCommand}" />
</UserControl.InputBindings>

ОБНОВЛЕНИЕ

Ниже приведен первый проход по расширениюСвязывание клавиш в соответствии с тем, что предлагает HB, вместе с базовой структурой моего расширенного класса Command.Привязка не компилируется с этой ошибкой: нельзя установить «Binding» в свойстве «CommandReference» типа «KeyBindingEx».«Связывание» можно установить только для свойства DependencyObject объекта Dependency.

<UserControl.InputBindings>
    <cmdRef:KeyBindingEx  CommandReference="{Binding SaveCommand}"/>
</UserControl.InputBindings>

   public class KeyBindingEx : KeyBinding
{
    public static readonly DependencyProperty CommandReferenceProperty = DependencyProperty
        .Register("VmCommand", typeof(CommandReference), typeof(KeyBindingEx),          
                  new PropertyMetadata(new PropertyChangedCallback(OnCommandReferenceChanged)));

    private static void OnCommandReferenceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
        var kb = (KeyBinding) d;
        var cmdRef = (VmCommand)e.NewValue;

        kb.Key = cmdRef.GestureKey;
        kb.Modifiers = cmdRef.GestureModifier;
        kb.Command = cmdRef;
    }

    public CommandReference CommandReference
    {
        get { return (CommandReference)GetValue(CommandReferenceProperty); }
        set { SetValue(CommandReferenceProperty, value); }
    }
} 

public class CommandReference : PropertyChangedBase, ICommandReference
{

    public Key GestureKey
    {
        get { return _gestureKey; }
        set
        {
            if (_gestureKey == value) return;

            _gestureKey = value;
            NotifyOfPropertyChange(() => GestureKey);
        }
    }
    private Key _gestureKey;

    ...
}


public class VmCommand : CommandReference, ICommand
{
    ...

    public KeyBinding ToKeyBinding()
    {
        return new KeyBinding
               {
                   Command = this, 
                   Key = GestureKey, 
                   Modifiers = GestureModifier
               };
   }

}

1 Ответ

1 голос
/ 16 июня 2011

В WPF вы можете либо создать расширение разметки , которое выполняет все присваивания для вас, либо вы подклассом KeyBinding с новым свойством вашего пользовательского типа команды, которое должно подключить свойство, измененное обратным вызовом, в котором затем снова Можно установить другие свойства. Сейчас не могу придумать ничего более изящного, чем это.

...