我非常喜欢WPF的一个方面是我可以在多大程度上以声明方式构建我的视图,即。使用XAML而不是代码隐藏。
现在我真的被InputBindings难倒,因为他们的CommandParameters不接受绑定。我想我的案例非常通用和简单,但我不知道如何在不诉诸代码的情况下做到这一点。考虑:
<ListBox Name="casingsListBox" ItemsSource="{Binding Path=Casings}" SelectedValuePath="Id">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Title}"/>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.InputBindings>
<!-- Doesn't work: -->
<MouseBinding Gesture="LeftDoubleClick"
Command="ApplicationCommands.Open"
CommandParameter="{Binding RelativeSource={RelativeSource Self} Path=SelectedValue}"/>
</ListBox.InputBindings>
</ListBox>
这不起作用,因为MouseBinding的CommandParameter的绑定表达式是非法的。
我问自己:如果我无法达到所选值,那么将鼠标单击手势添加到列表框的重点是什么?
当然,使用代码隐藏事件处理程序或通过命令使用者从命令源中提取id可以很容易地解决这个问题,但是有几个原因导致这种情况不合需要。除了大量代码隐藏代码首先击败(部分)WPF的目的之外,它还使得在Expression Blend中工作的UI设计人员的权力降低。而该死的,我的命令参数应该是一个id,而不是一些UI元素!!
主观:浏览了一段时间后,我对WPF相关问题中看到的代码数量感到震惊。我觉得我们的开发人员坚持我们的旧习惯并愉快地破解代码隐藏文件,而不是试图利用WPF应该代表的UI构建。你觉得怎么样?
但最重要的是:任何人都可以向我展示这个看似微不足道的问题的无代码解决方法吗?最好不要像this one那样可怕的黑客。
答案 0 :(得分:3)
我写了一个markup extension,允许InputBinding
的{{1}}数据绑定:
Command
您的情况略有不同,因为您想绑定<KeyBinding Modifiers="Control" Key="E" Command="{input:CommandBinding EditCommand}"/>
,但您可以调整我的代码以适应您的情况。请注意,此代码使用私有反射,它只能在完全信任的情况下工作,并且可以在WPF的更高版本中被破坏(实际上 在WPF 4.0中被破坏...我可以发布修改后的版本,如果你需要它。)
另一种选择是使用可在MVVM toolkit中找到的CommandReference类:
CommandParameter
同样,这是用于绑定<Window.Resources>
<c:CommandReference x:Key="EditCommandReference" Command="{Binding EditCommand}"/>
</Window.Resources>
...
<KeyBinding Modifiers="Control" Key="E" Command="{StaticResource EditCommandReference}"/>
属性,但可能适用于绑定Command
...
答案 1 :(得分:1)
解决此问题的新方法是使用Expression Triggers / Actions,它允许您在执行自定义操作的任意控件上设置键盘快捷键(例如触发命令)。