为什么当我将CommandParameter设置为某个Binding时,我的ICommand.CanExecute(ob
本文关键字:我的 ICommand CanExecute ob Binding CommandParameter 设置 为什么 | 更新日期: 2023-09-27 18:25:01
我在WPF中学习ICommands,遇到了一些简单代码的问题。我有一个带命令的按钮。如果我将命令参数设置为像这样的静态值CommandParameter="100"
,则CanExecute中parameter
参数的值为100,但是,当我通过像这样的绑定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。我从这里得到的。同样,如果我将CommandParameter更改为类似CommandParameter="100"
的somwthing,代码将按照我的预期运行(即,参数为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();
}
}
另一种可行的解决方案是将与命令本身的绑定定义为IsAsync=True
。但这会导致一些闪烁。所以这可能不是最好的选择。
示例:{Binding DoItCommand, IsAsync=True}
在InitializeComponent()
完成后,尝试引发MyCommand
类的CanExecuteChanged
-事件。可能,MyCommand
的CanExecute(object)
在第一次呈现时被调用以初始化按钮的状态,而绑定尚未全部初始化。