gpt4 book ai didi

wpf - ViewModel 中的 RoutedUICommand 与 ICommand 以及使用 InputBinding

转载 作者:行者123 更新时间:2023-12-02 04:16:02 26 4
gpt4 key购买 nike

基本 ICommand 接口(interface)实现(例如 DelegateCommand 和 RelayCommand)缺少 RoutedCommand 类中包含的 InputGestures 属性。此属性支持绑定(bind)到 KeyGesture,并且 RoutedUICommand 中的 Text 属性支持设置控件的 header 。例如:

<MenuItem Header="File">
<MenuItem Command="Open" />

结果是在"file"菜单项下出现一个标记为“打开 Ctrl + O”的菜单项。对于手势,InputBindings会将输入手势映射到命令,但您失去了 InputGestureText 支持。

如何在为 XAML 或 View 模型内的命令定义 KeyGestures 和 Text 的同时保持绑定(bind)到 View 模型的 ICommand 的简单性?例如,我希望在上下文菜单和主菜单中公开一个命令来显示相同​​的 Header 和 InputGestureText,如 RoutedUICommand 支持的那样,但该命令的实现位于 View 模型内部,而不是在 Window 后面的代码内部。/p>

最佳答案

查看反射器中的MenuItem,我们可以看到MenuItem如何获取Header/InputGesture值,即:

private static object CoerceInputGestureText(DependencyObject d, object value)
{
RoutedCommand command;
MenuItem item = (MenuItem) d;
if ((string.IsNullOrEmpty((string) value) &&
!item.HasNonDefaultValue(InputGestureTextProperty)) &&
((command = item.Command as RoutedCommand) != null))
{
InputGestureCollection inputGestures = command.InputGestures;
// Get appropriate gesture....
}
return value;
}

有类似的代码可以根据当前命令强制 Header 属性,但在本例中,它会查找 RoatedUICommand。这告诉我们,命令必须是 RoatedCommand/RoulatedUICommand 的实例,才能利用 MenuItem 的此功能。

查看反射器中的 RoatedCommand,发现没有一种简单的方法来创建派生自 RoatedCommandDelegateCommand,因为它是 CanExecute/Execute 方法不是虚拟的。

我们可以编写如下代码:

public class DelegateCommand : RoutedCommand, ICommand
{
bool ICommand.CanExecute(object parameter) {
// Insert delegate can execute logic
}
void ICommand.Execute(object parameter) {
// Insert delegate execute logic
}
}

但这并不能阻止调用 RoatedCommand 上的非显式 CanExecute/Execute 方法。这可能是也可能不是问题。

或者,我们可以创建一个自定义的 MenuItem,它足够智能,可以查找我们的 DelegateCommand(或其他地方)并使用它的文本/手势。

public class MyMenuItem : MenuItem {

static MyMenuItem() {
InputGestureTextProperty.OverrideMetadata(typeof(MyMenuItem),
new FrameworkPropertyMetadata(string.Empty, null, CoerceInputGestureText));
}

private static object CoerceInputGestureText(DependencyObject d, object value) {
MenuItem item = (MenuItem)d;
var command = item as DelegateCommand;
if ((string.IsNullOrEmpty((string)value) &&
DependencyPropertyHelper.GetValueSource(item, InputGestureTextProperty).BaseValueSource == BaseValueSource.Default &&
command != null) {
InputGestureCollection inputGestures = command.InputGestures;
// Get appropriate gesture....
}

// Call MenuItem Coerce
var coerce = InputGestureTextProperty.GetMetadata(typeof(MenuItem)).CoerceValueCallback;
return coerce(d, value);
}

}

关于wpf - ViewModel 中的 RoutedUICommand 与 ICommand 以及使用 InputBinding,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9131711/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com