在类对象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
Testmodel correctly inherits fromBindableBaseand usesSetPropertyto implementINotifyPropertyChanged. This ensures any changes to properties likeTestNumberwill notify subscribers (the View or ViewModel) of updates—this is exactly the responsibility of a model in MVVM. - Your
ViewModelalso inherits fromBindableBaseand wraps theTestinstance with a property usingSetProperty. This allows the View to react if you ever replace the entireTestobject, 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:
- Avoid unnecessary calls: Don't add this if no commands depend on
TestVM's existence or state—extraRaiseCanExecuteChangedcalls can introduce unnecessary performance overhead. - Handle internal model property changes: If commands depend on properties inside
Test(likeTestNumber), just callingRaiseCanExecuteChangedin theTestVMsetter isn't enough. You'll need to subscribe to theTestobject'sPropertyChangedevent 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
RaiseCanExecuteChangedin theTestVMsetter 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
相关产品推荐
相关产品推荐

