【发布时间】:2011-05-10 15:47:43
【问题描述】:
我目前正在处理一些 WPF 的东西。在将三个非常相似的形式合并为一个的过程中,我提出了一个问题。我编写的代码有效,但似乎远非最佳解决方案,所以我想我会向更广泛的受众寻求反馈和/或更好的解决方案。
一些背景
这三种形式共享很多 XAML 和代码隐藏,但每种形式都有一个不同的部分。我以一种形式保留了所有共享代码,并将不同的部分拆分为 UserControl,目的是在运行时将其中一个动态加载到容器中。我们使用的是 MVVM,所以表单有一个 ViewModel,新的 UserControls 也是如此。自然,表单的 ViewModel 充当父级,并包含新 UserControls 的 ViewModel 作为子级。
问题本身
最初,我使用带有 DataTemplateSelector 的 ContentControl 从多个 DataTemplate 中进行选择,每个 DataTemplate 都包含一个 UserControl。绑定到 ContentControl 的 Content 属性的父视图模型的属性在 DataTemplateSelector 中用于选择要使用的 DataTemplate。由于我并不过分迷恋必须设置 Content 属性,因此我切换到在 ContentControl 上使用带有 DataTriggers 的 Style,完成几乎相同的任务。但是,我需要能够遍历逻辑树(用于错误检查,如果您想知道的话),并且使用任何一种方法设置 ContentTemplate 似乎都不允许我继续沿着逻辑树从 ContentControl 进入 UserControl一旦加载。 UserControl 在容器中可见,并且通过它的 DataTemplate 定义具有与之关联的正确 ViewModel,但 ContentControl 没有逻辑子项,因为 Content 属性为空。因此,我回退到的解决方案是在表单的构造函数中检查父视图模型上的相关属性,并将其中一个 UserControl 显式实例化到 ContentControl 的 Content 属性中。完成后,我可以将逻辑树移入 UserControl。似乎必须有比这更好的做事方式,也许是在 XAML 中做这一切的某种方式。
所以...
有没有更好的方法来动态选择和实例化我的用户控件之一?我将表单中不同的部分拆分为 UserControls 的基本技术听起来合乎逻辑吗?看起来这应该是相当普遍的事情,重新使用一个窗口但改变它的某些部分,但我在谷歌的旅行中没有找到太多。也许我没有找对地方......
【问题讨论】:
-
您正在以正确的方式创建用户控件。我怀疑你做的不对是遍历逻辑树。如果您不需要这样做,则无需担心其余部分。所以也许我们应该解决这个问题。
-
第一个想法是最好的。我使用
DataTemplateSelector类,它支持在运行时切换视图,经过一些改动后可以在Silverlight中工作。
标签: c# wpf xaml mvvm user-controls