【问题标题】:I know I'm doing something wrong with RaiseCanExecuteChanged and CanExecute我知道我在 RaiseCanExecuteChanged 和 CanExecute 上做错了
【发布时间】:2012-08-28 16:45:44
【问题描述】:

在摆弄 MVVM 灯以让我的按钮在我想要的时候启用和禁用...

但是,我只知道我在这里做错了。我在被调用的同一区域中有 RaiseCanExecuteChanged 和 CanExecute。确定不是这样?

这是我的 xaml

<Button Margin="10, 25, 10, 25" VerticalAlignment="Center" HorizontalAlignment="Center" Width="50" Height="50" Grid.Column="1" Grid.Row="3" Content="Host">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Click">
            <mvvmLight:EventToCommand Command="{Binding HostChat}" MustToggleIsEnabled="True" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</Button>

这是我的代码

public override void InitializeViewAndViewModel()
{
    view = UnityContainer.Resolve<LoginPromptView>();
    viewModel = UnityContainer.Resolve<LoginPromptViewModel>();
    view.DataContext = viewModel;
    InjectViewIntoRegion(RegionNames.PopUpRegion, view, true);

    viewModel.HostChat = new DelegateCommand(ExecuteHostChat, CanHostChat);
    viewModel.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(ViewModelPropertyChanged);
}

void ViewModelPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
    if (e.PropertyName == "Name" || e.PropertyName == "Port" || e.PropertyName == "Address")
    {
        (viewModel.HostChat as DelegateCommand).RaiseCanExecuteChanged();
        (viewModel.HostChat as DelegateCommand).CanExecute();
    }
}

public void ExecuteHostChat()
{
}

public bool CanHostChat()
{
    if (String.IsNullOrEmpty(viewModel.Address) ||
        String.IsNullOrEmpty(viewModel.Port) ||
        String.IsNullOrEmpty(viewModel.Name))
    {
        return false;
    }
    else
        return true;
}

看看这两者是如何结合在一起的?这肯定是不对的。我的意思是……它对我有用……但它似乎有些不对劲。 RaiseCanExecuteChanged 不应该调用 CanExecute 吗?它没有......所以如果我没有那个 CanExecute 在那里,我的控件永远不会像我需要的那样切换它的 IsEnabled。

(viewModel.HostChat as DelegateCommand).RaiseCanExecuteChanged();
(viewModel.HostChat as DelegateCommand).CanExecute();

编辑:

如果我最终使用按钮的 Command 属性将我的命令绑定到... 一切正常。我可以删除 CanExecute 并留下 RaiseCanExecuteChanged ,一切正常。

像这样...这很好用。

<Button Command="{Binding HostChat}" Margin="10, 25, 10, 25" VerticalAlignment="Center" HorizontalAlignment="Center" Width="50" Height="50" Grid.Column="1" Grid.Row="3" Content="Host">
</Button>

void ViewModelPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
    if (e.PropertyName == "Name" || e.PropertyName == "Port" || e.PropertyName == "Address")
    {
        (viewModel.HostChat as DelegateCommand).RaiseCanExecuteChanged();
        //(viewModel.HostChat as DelegateCommand).CanExecute();
        //CommandManager.InvalidateRequerySuggested();
    }
}

【问题讨论】:

  • 进一步思考,它甚至无法正常工作。它启用按钮......但它不会禁用它。
  • 如果我使用 MVVM 灯的 RelayCommand 而不是 DelegateCommand... 一切似乎都很好。这真的是问题的根源吗?如果是这样,那似乎很愚蠢。

标签: wpf mvvm command canexecute


【解决方案1】:

CanExecute 方法只返回命令是否可以执行。它不做任何其他事情。你只需要RaiseCanExecuteChanged。在您的情况下,RaiseCanExecuteChanged 将调用 CanHostChat

【讨论】:

  • 如果我使用 Microsoft Prism DelegateCommand 和 MVVM Light EventToCommand,它似乎不会调用它。仅当我使用 MVVM Light 的 RelayCommand 更改 DelegateCommand 时它才有效。我在代码中找不到任何会导致这种情况的东西,但它确实是这样工作的。知道为什么吗?
  • 我从未使用过 EventToCommand。也许你必须使用 RelayCommand。但对我来说似乎是一个错误......它应该可以工作。
猜你喜欢
  • 2021-04-13
  • 2014-02-16
  • 1970-01-01
  • 1970-01-01
  • 2017-04-05
  • 2021-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多