查看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 属性,但在这种情况下,它会查找RoutedUICommand
. 这告诉我们,命令必须是RoutedCommand
/的实例RoutedUICommand
才能利用MenuItem
.
在反射器中查看RoutedCommand
,没有一种简单的方法可以创建DelegateCommand
从 派生的a RoutedCommand
,因为它的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
}
}
但这并不能阻止调用非显式CanExecute
/Execute
方法RoutedCommand
。这可能是也可能不是问题。
或者,我们可以创建一个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);
}
}