如果Command绑定解析为null,为什么启用了按钮?
好的,XAML非常简单,并使用MVVM绑定到ICommand SomeCommand { get; }
视图模型上的属性:
如果SomeCommand
返回null
,则启用该按钮。 (与ICommand
上的CanExecute(object param)
方法CanExecute(object param)
,因为没有实例可以调用该方法)
现在的问题是:为什么启用按钮? 你会怎么做?
如果按“启用”按钮,显然没有任何调用。 按钮看起来很有用,这很丑陋。
它已启用,因为这是默认状态。 自动禁用它将是一种导致其他问题的任意措施。
如果要禁用没有关联命令的按钮, SomeCommand
使用适当的转换器将IsEnabled
属性绑定到SomeCommand
,例如:
[ValueConversion(typeof(object), typeof(bool))] public class NullToBooleanConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return value !== null; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotSupportedException(); } }
我的同事发现了一个优雅的解决方案:使用绑定回退值!
public class NullCommand : ICommand { private static readonly Lazy _instance = new Lazy (() => new NullCommand()); private NullCommand() { } public event EventHandler CanExecuteChanged; public static ICommand Instance { get { return _instance.Value; } } public void Execute(object parameter) { throw new InvalidOperationException("NullCommand cannot be executed"); } public bool CanExecute(object parameter) { return false; } }
然后XAML看起来像:
这个解决方案的优点是,如果你破坏了Demeter法并且你在绑定路径中有一些点,每个实例可能变为null
,它会更好。
与Jon的答案非常相似,您可以使用带触发器的样式来标记在没有命令集时应禁用的按钮。
我更喜欢这种解决方案,因为它可以非常直接地解决问题,并且不需要任何新类型。