一些背景资料:
ICommand
的类中实现了MyCommand
接口。MyCommand.cs:
public class MyCommand : ICommand
{
public bool CanExecute(object parameter)
{
throw new NotImplementedException();
}
public void Execute(object parameter)
{
throw new NotImplementedException();
}
public event EventHandler CanExecuteChanged;
}
我发现当我尝试引用WPF 4.5应用程序中的MyCommand
类时,我收到以下错误:
类型'System.Windows.Input.ICommand'在程序集中定义 没有引用。您必须添加对程序集的引用 'System.Windows,Version = 2.0.5.0,Culture = neutral, PublicKeyToken = 7cec85d7bea7798e,Retargetable = Yes'。
我不确定为什么这种情况正在发生,或者我能做些什么来适当地解决它。在搜索完互联网后,我发现答案是在我的WPF应用程序中添加对System.Windows.dll 4.0.0.0
的引用。这样做允许我编译和运行应用程序,但我的IDE抱怨:
接口成员'无效 System.Windows.Markup.IComponentConnector.Connect(in,object)'不是 实现。
对于我的MainWindow.cs类,会发生这种情况。有没有更好的解决办法,只是处理这个错误,所以我不是在WPF应用程序中添加System.Windows.dll
的引用,它真的不需要它?而且我说它并不真的需要它,因为如果我将MyCommand
类复制/粘贴到Wpf应用程序中它可以正常工作。它只有一个问题,因为我试图将它用作便携式类库。
更新:
似乎除此之外还有更多的东西。我创建了一个新的Wpf应用程序并使用NuGet来引用MvvmCross解决方案(因为它有一个MvxCommand
对象)。当我这样做时,我得到同样的错误。
更新2:
我试图查看是否可以将MyCommand
类的实例分配给ICommand
:ICommand cmd = new MyCommand();
并收到以下错误:
无法将类型'PortableClassLibrary1.MyCommand'隐式转换为 'System.Windows.Input.ICommand'。存在显式转换(是 你错过了一个演员?)
出于某种原因,PCL似乎没有为我的桌面应用程序输入System.Windows.dll [2.0.5.0]
ICommand到System.dll [4.0.0.0]
ICommand ...呃!
更新3:
我上传了my solution,以便更清楚地了解问题所在。
更新4:
我在这个问题上打开了Microsoft connect ticket。
更新5:
在对这不起作用感到沮丧之后平静下来...而其他人告诉我他们没有得到相同的“界面”错误。我意识到添加System.Windows.dll
的“副作用”是ReSharper 8.1错误。我想是时候向ReSharper而不是微软抱怨了。 叹息
答案 0 :(得分:6)
您必须添加对程序集'System.Windows,Version = 2.0.5.0
的引用
建议很好,信息不是很好。很显然,你对版本号感到困惑。右键单击WPF项目,添加引用并勾选System.Windows
。这解决了你的问题。
缺少的魔法是System.Windows.dll引用程序集中的这一行:
[assembly: TypeForwardedTo(typeof(ICommand))]
将ICommand从System.Windows.dll转发到System.dll
请记住,c:\ program files(x86)\ reference assemblies子目录中的System.Windows.dll只是 引用程序集。它根本不包含任何代码或类型,只包含[TypeForwardedTo]属性。它充当“适配器”,弥合了不同.NET框架平台之间的差距。最终的可执行文件实际上根本不依赖于System.Windows.dll。
答案 1 :(得分:1)
这不是一个错误,它更多的是关于.NET Portable Subset中包含的内容。 MSBuild在抱怨方面是正确的。
如果你看看PortableClassLibrary的清单,你会看到实际上是对System.Windows的一个extern引用。
.assembly extern retargetable System.Windows
{
.publickeytoken = (7C EC 85 D7 BE A7 79 8E ) // |.....y.
.ver 2:0:5:0
}
如果你检查.NETPortable中实际包含的内容,你会发现所包含的系统程序集是v2.0.5.0
你可以在这里找到它 - > C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.0\Profile\Profile158\
...与V2.0.5.0中的System.Windows一样
从技术上讲,MSBuild在请求System.Windows时是正确的,因为在WPF的构建中没有明确包含它。
尽管TypeForwarding参数很有意思,但它仍然没有实际意义,因为在v2.0.5.0中,没有类型转发要做。
现在,如果您实际查看System.Windows v4.0.0.0,那么ICommand有一个TypeForwardedTo规则(使用反射器)
所以这里的问题更多的是设计问题,而不是任何事情。 System.Windows与WPF冲突,但这只是由于Window的其他实现。
所以要解决这个问题,请参考C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.0\Profile\Profile158\System.Windows.dll
中的v2.0.5.0 System.Windows(我会为此项目获取它的副本)。
您的最后一步是解决因此而发生的类型歧义...您将在System v4.0.0.0和System.Windows v2.0.5.0之间获得类型歧义,以便使用ICommand
您可以通过从“全局”别名中删除System.Windows(在引用上按F4)来解决此问题,并添加自定义别名,例如。 SomeAlias
然后通过它的别名引用它。
extern alias SomeAlias;
public partial class MainWindow : Window
{
private SomeAlias::System.Windows.Input.ICommand _command;
...etc...
Voila ..这真的很有趣,所以我详细介绍了here,我可以在其中加入截图(并谈谈ReSharper打嗝)
答案 2 :(得分:0)