c# - 为什么当我将 CommandParameter 设置为某个 Binding 时我的 ICommand.CanExecute(object) 参数为空,但当我将其设置为某个静态值时为非空?

标签 c# wpf icommand

我正在学习 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/

相关文章:

wpf - 在 WPF 中将文本框设置为 "nothing"但未更新 MV 值

c# - 属性更改时未调用按钮命令 CanExecute

wpf - 为什么绑定(bind)对 ICommand 属性进行特殊处理?

c# - 如何在单元测试中验证 Flurl Http 中的请求正文内容?

c# - 运行 Entity Framework 迁移时缺少根元素

c# - 在 MVVM 中,如果 UI 不需要更新,模型中的属性是否需要属性更改事件?

visual-studio-2010 - CS1684 对 System.Windows.Input.ICommand 类型的引用声称它在 'xxx' 中定义,但找不到

c# - Phabricator conduit.connect C# 证书错误

c# - ASP.NET Core 3.1 - WebApplicationFactory - WebApplicationFactoryContentRootAttribute 的正确用法是什么?

c# - 如何在此多绑定(bind)示例中设置源?