我们正在将WPF项目从MVVMLight库迁移到Microsoft CommunityToolkit库。
我们继续遵循共享的Microsoft migration documentation,并相应地更新了所有(大约1200个)命令。
当我们后来得到构建时,我们注意到事件在项目中没有正确触发,命令也不起作用。
但是,SetProperty()方法不运行我的RelayCommands。
下面我们已经解决了这个问题,只有一个命令,我们的用户模型。有超过100+模型和1200ish命令存在。
基本视图模型.cs
public class BaseViewModel : ObservableObject, IDisposable
{
protected bool _disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public virtual void Dispose(bool disposing)
{
if (_disposed.Equals(false))
{
if (disposing)
{
}
_disposed = true;
}
}
private bool _isSaved;
public bool IsSaved
{
get { return _isSaved; }
set
{
SetProperty(ref _isSaved, value, nameof(_isSaved));
}
}
}
登录视图模型
public class LoginViewModel : BaseViewModel
{
public LoginViewModel()
{
User = new UserModel();
User.PropertyChanged += User_PropertyChanged; // WHAT WE NEWLY ADDED
LoginCommand = new RelayCommand<Window>(OnLoginCommandExecuted, CanLoginCommandExecute);
CancelCommand = new RelayCommand<Window>(OnCancelCommandExecuted, CanCancelCommandExecute);
}
private void User_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (LoginCommand is not null) LoginCommand.NotifyCanExecuteChanged(); // We should notify it manually..
}
private UserModel _user;
public UserModel User
{
get { return _user; }
set
{
SetProperty(ref _user, value, nameof(_user));
}
}
public RelayCommand<Window>? LoginCommand { get; private set; }
public async void OnLoginCommandExecuted(Window window)
{
//DO STUFF
}
public bool CanLoginCommandExecute(Window window)
{
//DO STUFF
}
}
登录窗口.xaml
<Window
x:Class="ProjectName.LoginWindow"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
x:Name="loginWindow">
<Button x:Name="btnLogin" Command="{Binding LoginCommand}" CommandParameter="{Binding ElementName=loginWindow}" />
</Window>
有没有办法为活动模型中的所有命令触发NotifyCanExecuteChanged管理器?
在这种情况下我能做什么?下面的实现需要应用于所有的模型和命令吗?这是预期的情况吗?谢谢和快乐的编码。
1条答案
按热度按时间bq8i3lrv1#
有几件事你可以改变。
在分部类视图模型中,您可以执行以下操作:
IsSaved属性和更改通知的模板代码由代码生成器在分部类中创建。这将降低更改通知中断的风险(就像使用字段而不是属性时所遇到的风险),因为您只需定义私有成员。
您可以添加partial onchanged和onchanging方法,当匹配的属性名称更改或将要更改时,将调用这些方法。
当IsSaved更改时,属性将引发命令的canexecutechanged。
relay命令具有显式notifycanexecutechanged方法
https://learn.microsoft.com/en-us/dotnet/api/microsoft.toolkit.mvvm.input.relaycommand.notifycanexecutechanged?view=win-comm-toolkit-dotnet-7.1
如果没有一个属性适合您,您可以执行以下操作:
或者,您可以在视图模型中迭代relay命令,并调用notifycanexecutechanged。
另外请注意,mvvmlight的源代码是可用的。
我在一个.net6项目中使用过它。