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

在类对象Setter中实现RaiseCanExecuteChanged,求验证MVVM实现方案正确性

MVVM Implementation & RaiseCanExecuteChanged Best Practices

First, let's break down your questions step by step:

Is your MVVM implementation compliant with standard patterns?

Absolutely, your basic setup follows core MVVM best practices:

  • Your Test model correctly inherits from BindableBase and uses SetProperty to implement INotifyPropertyChanged. This ensures any changes to properties like TestNumber will notify subscribers (the View or ViewModel) of updates—this is exactly the responsibility of a model in MVVM.
  • Your ViewModel also inherits from BindableBase and wraps the Test instance with a property using SetProperty. This allows the View to react if you ever replace the entire Test object, which is a valid approach when you need to swap out the full model instance.

Is it reasonable to call RaiseCanExecuteChanged in a class object's setter?

This depends on your specific use case, but it can be entirely reasonable when done intentionally.

Here's when it makes sense:
If you have commands in your ViewModel whose CanExecute state depends on the TestVM object (e.g., a command that only works if TestVM is not null, or if TestVM.TestNumber meets certain criteria), calling RaiseCanExecuteChanged in the TestVM setter ensures the command's state updates immediately when the object is replaced.

But keep two key considerations in mind:

  1. Avoid unnecessary calls: Don't add this if no commands depend on TestVM's existence or state—extra RaiseCanExecuteChanged calls can introduce unnecessary performance overhead.
  2. Handle internal model property changes: If commands depend on properties inside Test (like TestNumber), just calling RaiseCanExecuteChanged in the TestVM setter isn't enough. You'll need to subscribe to the Test object's PropertyChanged event to trigger command updates when its internal properties change.

Example of a robust implementation:

class ViewModel : BindableBase
{
    private Test _testVM;
    public Test TestVM
    {
        get { return _testVM; }
        set 
        {
            // Unsubscribe from the old instance's PropertyChanged event first
            if (_testVM != null)
            {
                _testVM.PropertyChanged -= OnTestVMPropertyChanged;
            }

            // Update the instance and check if the value actually changed
            if (SetProperty(ref _testVM, value))
            {
                // Subscribe to the new instance's PropertyChanged event
                if (_testVM != null)
                {
                    _testVM.PropertyChanged += OnTestVMPropertyChanged;
                }

                // Raise command state updates
                YourCommand.RaiseCanExecuteChanged();
                AnotherDependentCommand.RaiseCanExecuteChanged();
            }
        }
    }

    private void OnTestVMPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        // Trigger command updates when any property in Test changes
        // You can filter by e.PropertyName if only specific properties affect commands
        YourCommand.RaiseCanExecuteChanged();
        AnotherDependentCommand.RaiseCanExecuteChanged();
    }

    // Example commands that depend on TestVM or its properties
    public ICommand YourCommand { get; }
    public ICommand AnotherDependentCommand { get; }
}

Final Takeaways

  • Your core MVVM structure is solid and aligns with standard patterns.
  • Calling RaiseCanExecuteChanged in the TestVM setter is valid when commands depend on that object's state—just remember to pair it with event subscriptions if you need to react to internal model property changes.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:40:19