我们使用以下机制/语法来绑定XAML中的命令:
Command="{Binding CommandAggregator[FooCmd], Mode=OneTime}"
此处,CommandAggregator
是一个对象,您可以使用索引器(带有string
参数)来获取实际命令。
聚合器的命令注册让我有些烦恼,因为我们仍然使用魔术字符串作为命令名称,如下所示:
this.CommandAggregator.SetCommand("FooCmd", new RelayCommand(execute, canExecute));
虽然我不一定喜欢这整个过程,但我无法改变太多。我现在要做的一件事就是使用魔术字符串退出,使它们成为静态static readonly string
类中的常量或CommandName
个对象。
但是否可以在XAML中定义绑定并引用常量(比如说CommandName.Foo
)?我想过使用{x:Static ...}
,但我不知道如何将返回的值放入索引器。
答案 0 :(得分:1)
你可以实现一个IValueConverter
,它将根据转换器从CommandAggregator返回一个命令参数:
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var aggregator = value as CommandAggregator;
var cmd = parameter as string;
if (aggregator != null && cmd != null)
return aggregator[cmd];
return null;
}
并从xaml传递参数:
Command="{Binding Path=CommandAggregator,
Converter={StaticResource MyConverter},
ConverterParameter={x:Static Constants.FooCmd},
Mode=OneTime}"
答案 1 :(得分:0)
不确定这是否是最好的方法,但是对我有用。我不喜欢在调试器中显示我的Relay命令的CmdWhatEvers太多,因此将它们移动到字典中,该字典看起来类似于CommandAggregator,然后用静态字符串索引它们(魔术字符串对我造成了很多绑定失败。 ) 无论如何,我的字符串常量位于一个静态类中
internal static class Str
{
public static readonly string CmdReset = "CmdReset";
}
在视图模型中
internal class CtrlVm : ViewModelBase
{
public Dictionary<string, IRelayCommand> Commands { get; }
public CtrlVm()
{
Commands = new Dictionary<string, IRelayCommand>()
{
// My relay command class takes, Execute, CanExecute
// and a Header parameter, that I use in binding
Str.CmdReset, new RelayCommand(Reset, CanReset, "Reset");
},
}
private bool CanReset(object parameter)
{
return bHasChanges; // or whatever
}
private void Reset(object parameter)
{
// do the reset work
}
}
然后在Xaml中
<Button Command= "{Binding Commands[CmdReset]}"
Content= "{Binding Commands[CmdReset].Header}"/>