我想在我的应用程序中添加一些通用键盘快捷键。目前,在每个View XAML中我都添加了以下代码:
500 HTML::Parser object version 3.35 does not match bootstrap parameter 3.72
为了概括这一点,我想继承WPF Window类并使用新创建的子类。现在我想知道如何在相应的代码中绑定这些键盘命令。目前它看起来像这样:
<Window.InputBindings>
<KeyBinding Command="{Binding ZoomInCommand}" Key="Add" Modifiers="Control" />
<KeyBinding Command="{Binding ZoomOutCommand}" Key="Subtract" Modifiers="Control" />
</Window.InputBindings>
但这对我来说并不合适,因为我需要直接访问DataContext并转换它而不是使用Binding()对象。如何更改代码以使其看起来更像MVVM?
答案 0 :(得分:1)
您需要的是依赖属性。
在MyWindow
中,为两个命令创建ICommand
依赖项属性,您还需要实现回调方法依赖项属性值发生变化,这里是ZoomInCommand
的一个:
public ICommand ZoomInCommand
{
get { return (ICommand)GetValue(ZoomInCommandProperty); }
set { SetValue(ZoomInCommandProperty, value); }
}
// Using a DependencyProperty as the backing store for ZoomInCommand. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ZoomInCommandProperty =
DependencyProperty.Register("ZoomInCommand", typeof(ICommand), typeof(MyWindow), new PropertyMetadata(null, new PropertyChangedCallback(OnZoomInCommandChanged)));
...
private static void OnZoomInCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
MyWindow wnd = (MyWindow)d;
//Remove the old key binding if there is one.
wnd.RemoveInputBinding(e.OldValue as ICommand);
//Add the new input binding.
if (e.NewValue != null)
wnd.InputBindings.Add(new KeyBinding((ICommand)e.NewValue, Key.Add, ModifierKeys.Control));
}
private void RemoveInputBinding(ICommand command)
{
if (command == null)
return;
//Find the old binding if there is one.
InputBinding oldBinding = null;
foreach (InputBinding binding in InputBindings)
{
if (binding.Command == command)
{
oldBinding = binding;
break;
}
}
//Remove the old input binding.
if (oldBinding != null)
InputBindings.Remove(oldBinding);
}
那么上面的代码到底是做什么的呢?
在依赖项属性上,可以选择使用PropertyChangedCallback
方法,只要属性值发生变化就会触发,这很好,因为我们可以使用它来删除旧的{{如果要更改值,请创建一个新的InputBinding
。在您的情况下,只要InputBinding
发生更改,该值就会发生变化。
每当属性值发生变化时,步骤都非常简单:
DataContext
的旧InputCommand
。ICommand
添加新的InputCommand
。我创建了一个方便的ICommand
方法,这样可以更容易地为您的其他依赖项属性重用代码,这取决于您实现。
要将这一切放在一起,在RemoveInputBinding
事件处理程序中,您只需编写手动绑定:
DataContextChanged
这将确保您不再需要担心将private void MyWindow_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
//Bind this.ZoomInCommand to DataContext.ZoomInCommand
Binding zoomInCommandBinding = new Binding("ZoomInCommand");
zoomInCommandBinding.Source = DataContext;
this.SetBinding(MyWindow.ZoomInCommandProperty, zoomInCommandBinding);
...
}
转换为DataContext
,只需尝试绑定到IZoomableViewModel
。如果ZoomInCommand
中没有这样的命令,那么它将无声地失败。如果它确实成功,则会触发DataContext
并为该命令创建PropertyChangedCallback
。
答案 1 :(得分:1)
我发现了一个很好用的简单解决方案,似乎模仿了XAML解析器的行为。基本上,对于放大功能,我将以下代码放在MyWindow构造函数中:
var zoomInKeyBinding = new KeyBinding { Key = Key.Add, Modifiers = ModifierKeys.Control };
BindingOperations.SetBinding(
zoomInKeyBinding,
InputBinding.CommandProperty,
new Binding { Path = new PropertyPath("ZoomInCommand") }
);
InputBindings.Add(zoomInKeyBinding);
当然绑定的ViewModel需要适当地实现ZoomInCommand。