C++/CLI、XAML和事件处理程序

8
我是一个新手在Windows领域,我认为我在一个问题上迷失了方向。我希望得到一些来自有C++/CLI、WPF和XAML经验的人的建议。
我有一些win32代码,需要运行WPF GUI。我找到了这个微软演练样例,使用了C++/CLI。我根据我的目的进行了改编,效果很好。
接下来,我想摆脱程序化的WPF内容,改用XAML。这样我就可以将XAML交给设计师,让自己不再参与UI设计过程中,因为我绝对不属于那个领域。在阅读了MSDN上的WPF和Win32互操作项目部分后,我决定选择XamlReader::Load选项,并在运行时加载未编译的XAML。我的XAML标记是一个CanvasUIElement,我以编程方式将其作为我的根GridC++/CLI元素的子元素添加。这工作得很好。
现在我想在XAML中为控件添加事件处理程序。这就是我开始遇到麻烦的地方。我相信我的Windows世界的普遍无知是导致问题的95%。
我从Rob Relyea的页面开始,概述了各种XAML和事件处理程序选项。
我决定尝试将XAML编译为C# DLL。它基本上是与我在运行时加载案例中使用的XAML相同。我像以前一样实例化对象并以编程方式将其作为子对象添加。但是...我什么也没得到,只有一个黑色窗口。也没有抛出任何异常。我很困惑。
我的问题是,我是否走在正确的道路上?关于XAML和事件处理程序的页面说,您可以在.Net Framework 4中使用未编译的XAML中定义的事件处理程序。我应该咬紧牙关,转到VS 2010(我目前正在使用VS 2008),以便我可以使用.Net Framework 4并坚持使用未编译的XAML吗?这种做法有什么需要注意的地方吗?

如果您认为编译的C# DLL是一个合理的路径,那么您有什么想法可以帮助我调试遇到的问题吗?

或者,是否有更好、完全不同的方法?

提前感谢您的建议。

Polly


1
你的方向错了。在 WPF 中,工具非常重要,无论是通过 IDE 还是 Expression。C++/CLI 完全没有任何工具集成。而且从使用 C++/CLI 到使用 C# 没有任何优势。 - Hans Passant
Hans,感谢您的评论。我通常也更喜欢走已经被证明可行的道路(即C#而非C++/CLI),但在这种情况下,我需要保留大量的C++代码投资。在这种情况下,我的目标是为现有代码提供一个更漂亮的外观。 - Polly
非托管代码可以通过C++/CLI轻松调用托管代码,因此您可以使用C#编写GUI,但由C++代码调用。虽然通常是通过C++/CLI让C#调用C++,但您的方法同样有效。如果您不想使用C#,则必须在代码后台中分配事件处理程序,并进行一些棘手的调用,如FindName或搜索可视树。这是可以做到的,但我认为制作C#程序集供C++代码使用会更容易些。 - Ed Bayiates
2个回答

3
我认为正确的答案取决于一些问题,只有您才能决定,但我将从这样一个假设开始,即您的C ++代码库足够大且复杂,值得保留。
除此之外,下一个决策点是您是否在保留的C ++中拥有UI(可能是GDI)代码,还是只有非UI代码。如果您试图仅保留非UI代码,则应考虑将更多UI责任推入C#中。也许您可以在C#中构建视图、事件处理程序,甚至是视图模型。这将使您更好地利用VS工具。
如果您有大量的C++ UI代码需要保留,那么您目前的路径更有意义。我认为这并不是不可能的,但你将面临相当大的挑战。关键的例子是Visual Studio 2010。它是混合应用程序的杰出例子,并且具有GDI和WPF并存的功能,不像我曾经看到或听说过的任何其他应用程序。我发现一系列博客文章非常有趣,描述了Visual Studio团队为实现这种集成所做的一些方面(The Visual Studio Blog)。
我还发现了这个视频Henry Sowizral on Refacing C++ with WPF in Expression Design,我自己没有看过,但讨论了在现有的MFC C++应用程序上放置WPF UI的方法。
祝好运。

关于你的问题的第一部分,我没有具体的建议,只能说将更多的责任放在C#中可以让你构建一个小的存根应用程序,如果必要的话,这可以在诊断问题方面起到很大的作用。


这些都是很好的观点。然而,在这种情况下,我有一些大量的性能敏感代码是用C++编写的,我想给它一个更具吸引力的WPF GUI。GUI代码并不是性能敏感的。出于性能原因,我决定使用C++应用程序来调用WPF代码进行偶尔的GUI操作,而不是使用C#应用程序来调用C++代码进行长时间计算。不过,我承认这是基于直觉而不是对win32/.Net互操作性能考虑的彻底了解。你认为我理解错了吗?谢谢你的指导,我会看一下的。 - Polly
基于这里的信息,很难更加具体。我想你可以创建一个 ViewModel(搜索 MVVM);它基本上是你想在 Xaml 中显示的数据模型。然后将你的 Xaml 绑定到 C# ViewModel,然后在 C++ 中操纵或响应 ViewModel。这将使 Xaml 部分更加传统和可混合。我不知道在 C++ 中放置 ViewModel 是否可能。除了语言问题外,Xaml 与 Win32 方法论之间存在不匹配。 - jdasilva

2
感谢大家的回复。关于卡在C# DLL上的问题,我找到了这个C++/CLI示例:http://msdn.microsoft.com/en-us/library/aa970266.aspx。使用它,我找到了我的错误,并且能够无问题地加载WPF。
然而,加载C# DLL的整个动机是我理解这是以编程方式附加事件处理程序的方法。根据AresAvatar的建议,我发现我可以使用FindName来附加处理程序 - 在C# DLL中,但它也适用于我的原始松散XAML方法。所以,我并不需要C# DLL!
现在一切都很好。再次感谢您的所有帮助和建议。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接