2014-05-06 45 views
2

我想为.NET 4.5,Windows 8,Windows Phone 8.1和Silverlight 5创建一个PCL,但是我无法使用ICommand在检查所有这些平台时,尽管所有这些平台都应该支持它,根据MSDNCan not use ICommand in Portable Class Libary for .NET 4.5,W8,WP8.1 and SL5

重现步骤:

  • 创建.NET 4.5的PCL项目,Windows 8中,和Silverlight 5
  • 创建一个实现ICommand的一类,并生成成员
  • 生成成功

  • 在项目设置中添加Windows Phone 8.1

  • 构建失败(无法找到Sys tem.Windows)
  • 如果您删除了Silverlight或WP,它可以正常工作,但两者同时处于活动状态并不会。

这是错误吗?或者我错过了什么?

+0

看看这里... http://stackoverflow.com/questions/20478138/portable-class-library-icommand-compilation-error-in-wpf-not-sure-how-to-reso – Mashton

+0

我没有,但这是一个稍微不同的问题,不幸的是这个解决方案不适用于此。 –

回答

1

不幸的是,我们无法在同时针对Silverlight 5和Windows Phone 8.1的PCL中支持ICommand(以及其他ViewModel类型,例如ObservableCollection)。我建议从PCL中删除SL5支持,并通过非便携式库支持该平台。

+0

如果您花一点时间解释完全*为什么*您无法支持,我们可能会少收多少关于PCL的问题。 SO不是论坛。 –

+0

@HansPassant我们无法支持它的原因与PCL如何实现的技术细节有关,大多数开发人员不需要知道或关心这些细节。问题在于这些类型在Silverlight中的System.Windows.dll中,但该DLL在Windows Phone上具有Windows Phone Silverlight UI堆栈,该应用程序在Windows Phone XAML应用程序中被阻止(因为它们具有不同的UI堆栈)。 –

+0

@DanielPlaisted:我知道这个答案已经有一年了,但是OP不能利用“NuGet诱饵和开关”技术?事实上,2014年5月撰写的一篇博文特别让你评论如何实现这一目标! http://dotnetbyexample.blogspot.com/2014/05/writing-behaviors-in-pcl-for-windows.html –

0

我相信你可以在这里完成的最好的解决方案是创建一个共享的项目,并把它的所有代码放在里面(需要VS2013.2 +),然后为除SL5之外的所有东西创建一个PCL(配置文件259),然后一个SL5类库(共享引用共享项目)。这将使您能够以所有平台为目标(但不幸的是,需要两个空组件才能支持通用平台)。

@DanielPlaisted是否将MS重构非常泛型类型(如ICommand)到较少平台特定的程序集/名称空间的任何输入? (抱歉提问,但你似乎有内部知识)。

+0

我正在对此进行更多的考虑,因为我不太喜欢这个解决方案。我把我的工作放在这里:http://git.acrotech.io/acrotech.portableviewmodel.commands 基本上这个想法是创建一个通用的可移植命令库(配置文件344),它不提供System.Windows.Input.ICommand支持,而是提供ICommand的镜像兼容性副本。然后在共享项目中另外提供一个支持命令绑定到便携式ICommand接口的子类按钮控件(引用所有支持WPF的平台)。 反馈欢迎 – pjs

0

虽然这个问题已有一年了,但我遇到了一篇博文,可以帮助解决这个问题:http://dotnetbyexample.blogspot.com/2014/05/writing-behaviors-in-pcl-for-windows.html - 此博客也包含一个下载示例,因此您可以检查其内部工作原理。该博客与IBehavior界面一起使用,但conept是相同的。


基本上,该技术被称为“的NuGet诱饵和开关”;您需要创建一个NuGet包,其中包含一个PCL库和一个特定于平台的库(每个平台都有一个库)。

让我们假设你的PCL将被称为“AwesomeMvvm”。你将需要:

  • AwesomeMvvm(便携式类库)
  • AwesomeMvvm.Silverlight
  • AwesomeMvvm.Windows81
  • ...

当您尝试使用ICommand接口在便携式类库(PCL),你会得到一个错误,说明Cannot resolve symbol ICommand。要解决这个问题,只需创建一个接口,确保它位于相同的命名空间System.Windows.Input中。您的便携式类库现在可以编译!

既然您的便携式类库已编译完成,请创建特定于平台的库并为它们添加对您的便携式类库的引用。每个这些库的唯一需要的是包含在TypeForwardedToAttribute作为组件级属性一个代码文件:

[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Windows.Input.ICommand))] 

的最后一步是创建一个包含便携式类库单个NuGet包,以及每个平台特定图书馆。如果你做的一切都正确,从你的NuGet提要添加一个引用,一切都应该工作得很好。 NuGet会尽可能地选择特定于平台的库,每个库都依赖于可移植的类库。诀窍是,在运行时它将使用本地版本ICommand,因为您指定将您的可移植类库版本转发到特定于平台的版本。