You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Fody PropertyChanged时属性变更未触发CanExecute的问题

问题原因与解决方案

核心问题

你的ViewModel没有监听MyModel内部属性的变更事件,同时Model的分部类配置存在冗余,导致Fody的属性变更通知逻辑未正确生效,最终命令的CanExecute状态无法自动更新。

1. Model分部类的冗余配置干扰Fody注入

你手动声明了PropertyChanged事件,但[AddINotifyPropertyChangedInterface]特性会自动为类实现INotifyPropertyChanged接口(包括事件定义和属性变更通知逻辑),手动添加事件会破坏Fody的自动注入流程。

修复代码:

namespace FodyPropertyChange
{
    [AddINotifyPropertyChangedInterface]
    public partial class Model
    {
        // 移除手动声明的PropertyChanged事件,仅保留特性即可
    }
}

2. ViewModel未感知Model内部属性变化

当前ViewModel仅在MyModel实例被替换时(即MyModel属性的setter)调用TestCommand.RaiseCanExecuteChanged(),但MyModel内部的Name/Age属性变化时,ViewModel无法感知,因此不会更新命令的可执行状态。

修复代码:

public class MainWindowViewModel : BindableBase
{
    public DelegateCommand TestCommand { get; set; }

    public MainWindowViewModel()
    {
        TestCommand = new DelegateCommand(OnTestCommand, CanExecute);
        // 订阅MyModel的属性变更事件
        MyModel.PropertyChanged += MyModel_PropertyChanged;
    }

    private void MyModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        // Model内部属性变化时,更新命令可执行状态
        TestCommand.RaiseCanExecuteChanged();
    }

    private bool CanExecute()
    {
        return MyModel.Age > 0 && !string.IsNullOrEmpty(MyModel.Name);
    }

    private void OnTestCommand()
    {
        MessageBox.Show("Hi");
    }

    private Model _MyModel = new Model();
    public Model MyModel
    {
        get { return _MyModel; }
        set
        {
            // 先取消旧实例的事件订阅,避免内存泄漏
            if (_MyModel != null)
                _MyModel.PropertyChanged -= MyModel_PropertyChanged;
            
            SetProperty(ref _MyModel, value);
            
            // 订阅新实例的事件
            if (_MyModel != null)
                _MyModel.PropertyChanged += MyModel_PropertyChanged;
            
            TestCommand.RaiseCanExecuteChanged();
        }
    }
}

注:ViewModel继承的BindableBase已实现INotifyPropertyChanged,无需手动重复声明接口和事件。

3. 额外验证点

  • 确认已通过NuGet安装PropertyChanged.Fody包;
  • 检查FodyWeavers.xml的“复制到输出目录”设置为“始终复制”,确保编译时Fody能读取配置。

修复完成后,当文本框修改MyModel的属性时,Model会触发PropertyChanged事件,ViewModel收到事件后更新命令的可执行状态,按钮会根据CanExecute的返回值自动启用/禁用。

内容的提问来源于stack exchange,提问作者Khosro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 19:31:20