在MVVM Light 5.2.0.37222中找不到GalaSoft.MvvvmLight.CommandWpf命名空
本文关键字:MvvvmLight GalaSoft CommandWpf 找不到 Light MVVM 37222 | 更新日期: 2023-09-27 18:21:17
我刚刚尝试将我的一个WPF项目从MVVM Light 4.2.30更新到5.2。在那之后,我注意到我的RelayCommands
不再激发他们的CanExecute
方法。
经过快速搜索,我找到了几篇文章,解释了这个问题,并建议使用GalaSoft.MvvmLight.CommandWpf
命名空间而不是GalaSoft.MvvmLight.Command
。但是,我找不到GalaSoft.MvvmLight.CommandWpf
命名空间。当我在Visual Studio的"对象浏览器"中查看GalaSoft.MvvVMAlaSoft.MvvmLight.dll时,我也找不到这个命名空间。
除了我,似乎没有其他人有这个问题——你知道我做错了什么吗?
更新:
我创建了一个小的示例项目,展示了我目前如何在MVVM light:的4.2.30版本中使用RelayCommands及其CanExecute方法
public class ViewModel : ViewModelBase
{
private bool _isReadOnly = false;
public ViewModel ()
{
this.DoSomethingCommand = new RelayCommand(DoSomething, CanDoSomething);
}
public bool IsReadOnly
{
get
{
return _isReadOnly;
}
set
{
_isReadOnly = value;
this.RaisePropertyChanged("IsReadOnly");
// With MVVMLight 4.2.30.23246 I did not need to call the RaiseCanExecuteChanged on any of my RelayCommands
// DoSomethingCommand.RaiseCanExecuteChanged();
}
}
public RelayCommand DoSomethingCommand { get; set; }
private bool CanDoSomething()
{
return !this.IsReadOnly;
}
private void DoSomething()
{
MessageBox.Show("Let's break the MVVM idea...");
}
}
视图的XAML代码为:
<Window x:Class="MVVMLight5.2CanExecuteTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MVVMLight5._2CanExecuteTest"
mc:Ignorable="d"
Title="Test" Height="150" Width="200">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<CheckBox HorizontalAlignment="Center" Grid.Row="0" Grid.Column="0" Content="Is read only" IsChecked="{Binding IsReadOnly, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<Button Grid.Row="1" Grid.Column="0" Content="Break me" Command="{Binding DoSomethingCommand}"/>
</Grid>
我的目标是,如果我在视图中有一个使用"DoSomethingCommand"作为命令的按钮,那么当我的IsReadOnly属性设置为false时,该按钮应该被禁用。当使用MVVM灯4.2.30时,到目前为止,这没有任何额外的功能,但在MVVM灯5.2中,我需要添加DoSomethingCommand.RiseCanExecuteChanged();以使该按钮在视图中禁用。
我能用新的MVVM轻框架以某种方式获得旧的行为吗?
TL;DR:确保您有对GalaSoft.MvvvmLight.Platform的引用,然后您可以使用CommandWpf
命名空间。或者,仔细检查您是否链接到了.NET 4.5版本的MVVM Light;我想你正在链接到.NET 4.0版本的
Laurent(MVVMLight的作者)实际上已经在他的博客上谈到了这一切。关于他为什么创建了一个不同的名称空间:
在MVVM Light的可移植类库版本中,没有CommandManager。
我考虑的第一个明显的解决方案是:将RelayCommand从GalaSoft.MvvvmLight.dll程序集中移到GalaSoft.MvvmLight.Platform.dll中。因为这个dll不是PCL(因此得名"平台"),所以它可以包含特定于平台的元素。如果我把RelayCommand移到那里,它将像以前一样与CommandManager一起工作。然而,它将不再适用于基于PCL的程序集,这是一个真正的问题。这就是为什么我决定反对这个决定。
相反,我决定复制RelayCommand类。如果您检查WPF源代码,您将看到这个类在GalaSoft.MvvvmLight程序集中链接,也在GalaSoft.mvvvmlight.Platform程序集中链接。这是同一个班!然而,为了避免冲突,平台程序集中的冲突是在GalaSoft.MvvvmLight.CommandWpf命名空间中声明的。
在这种背景下,我仍然有点困惑,为什么事情会是这样。当我分解Nuget上发布的库时,我看到的是:
MvvvmLightLibs.5.2.0.0''lib''net40(程序集版本5.2.0.37222):
namespace GalaSoft.MvvmLight.Command
{
/// <omitted, see below>
public class RelayCommand<T> : ICommand
{
private readonly WeakAction<T> _execute;
private readonly WeakFunc<T, bool> _canExecute;
/// <summary>
/// Occurs when changes occur that affect whether the command should execute.
///
/// </summary>
public event EventHandler CanExecuteChanged;
MvvvmLightLibs.5.2.0.0''lib''net45(程序集版本5.2.0.37223):
namespace GalaSoft.MvvmLight.Command
{
/// <omitted, see below>
public class RelayCommand<T> : ICommand
{
private readonly WeakAction<T> _execute;
private readonly WeakFunc<T, bool> _canExecute;
/// <summary>
/// Occurs when changes occur that affect whether the command should execute.
///
/// </summary>
public event EventHandler CanExecuteChanged
{
add
{
if (this._canExecute == null)
return;
CommandManager.RequerySuggested += value;
}
remove
{
if (this._canExecute == null)
return;
CommandManager.RequerySuggested -= value;
}
}
请注意,CanExecuteChanged
的4.5版本使用CommandManager
类,这就是为什么您永远不需要调用RaiseCanExecuteChanged()
。4.0版本只是一个常规事件,因此您需要自己调用RaiseCanExecuteChanged()
。
另外请注意,两者的程序集版本不同,因为在您的问题中,您说您使用的是5.2.0.37222,所以我认为您正在使用4.0库。这就是为什么我认为仅仅参考4.5版本就可以修复它
不幸的是,我无法通过查看源代码来理解为什么这两个版本不同。这三个常量都没有在.NET 4.0版本的项目中定义,那么为什么它不使用CommandManager
生成分支呢?