我正在学习 WPF 中的 ICommands,我遇到了一些简单代码的问题。我有一个带命令的按钮。如果我将命令参数设置为这样的静态值,CommandParameter="100"
,CanExecute 中的 parameter
参数的值为 100,但是当我设置该值时命令参数通过这样的绑定(bind) CommandParameter="{Binding}"
,CanExecute 中的 parameter
参数的值为 null。
这是我的 ICommand:
internal class MyCommand : ICommand
{
public bool CanExecute(object parameter) //parameter is null
{
var datacontext = parameter as MyDataContext;
if (datacontext == null)
return false;
return datacontext.IsChecked == true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
throw new NotImplementedException();
}
}
这是 XAML 代码。请注意,我在设置命令之前设置了 CommandParameter。我知道了 from here .同样,如果我将 CommandParameter 更改为 CommandParameter="100"
之类的东西,代码将按照我的预期运行(即参数为 100,而不是 null)。
<StackPanel Orientation="Vertical">
<StackPanel.Resources>
<cmd:MyCommand x:Key="kCmd" />
</StackPanel.Resources>
<CheckBox Content="Check this to enable button" IsChecked="{Binding IsChecked}" />
<Button Content="Click" CommandParameter="{Binding}"
Command="{StaticResource kCmd}" />
</StackPanel>
这是我的 MainWindow 代码隐藏。在这里,我在调用 InitializeComponent()
之前设置 DataContext。在调试时,我发现 InitializeComponent()
触发了对 ICommand 的 CanExecute(object)
的调用。
public MainWindow()
{
this.DataContext = new MyDataContext();
InitializeComponent();
}
我的 MyDataContext
类非常简单,所以我将其省略。
最佳答案
这也是通过引发 CanExecuteChanged< 从
命令的事件。当您使用 FrameworkElement
事件的 Loaded
强制重新评估 CanExecute
的解决方案DataTemplate
并且遇到此问题时,尤其可以使用这种方法。
例子:
<DataTemplate x:Key="MyTemplate">
<Grid Loaded="HandleLoaded">
...
和代码背后:
void HandleLoaded(object sender, RoutedEventArgs e)
{
var viewModel = this.DataContext as ViewModel;
if (viewModel != null)
{
viewModel.DoItCommand.RaiseCanExecuteChanged();
}
}
另一种可行的解决方案是将命令本身的绑定(bind)定义为 IsAsync=True
。但这会导致一些闪烁。所以这可能不是最佳选择。
示例:{Binding DoItCommand, IsAsync=True}
关于c# - 为什么当我将 CommandParameter 设置为某个 Binding 时我的 ICommand.CanExecute(object) 参数为空,但当我将其设置为某个静态值时为非空?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26102118/