C# 使用Prism、MVVM、MEF在WPF中动态生成控件

C# 使用Prism、MVVM、MEF在WPF中动态生成控件,c#,wpf,mvvm,prism,mef,C#,Wpf,Mvvm,Prism,Mef,我将WPF与Prism和MEF一起用于我的应用程序。需要动态创建控件。这就是我的问题 据我所知,我不应该在代码隐藏(SomeFile.xaml.cs)中包含代码,以使代码易于测试。因此,代码实际上应该移动到ViewModel 但我的代码动态生成UI控件。我认为ViewModel不应该知道任何关于控件的信息 那么我应该在哪里以及如何编写这段代码呢??正确的方法是什么? 希望我说清楚 感谢在我看来,视图有责任呈现viewmodel提供的数据/模型。虽然在viewmodel中保留尽可能多的模型->视图

我将WPF与Prism和MEF一起用于我的应用程序。需要动态创建控件。这就是我的问题

据我所知,我不应该在代码隐藏(SomeFile.xaml.cs)中包含代码,以使代码易于测试。因此,代码实际上应该移动到ViewModel

但我的代码动态生成UI控件。我认为ViewModel不应该知道任何关于控件的信息

那么我应该在哪里以及如何编写这段代码呢??正确的方法是什么? 希望我说清楚


感谢

在我看来,视图有责任呈现viewmodel提供的数据/模型。虽然在viewmodel中保留尽可能多的模型->视图转换逻辑是理想的,但控件的创建增加了移动到viewmodel的复杂性,因为它可以添加耦合或基础结构

虽然你可以: 1) 让viewmodel直接访问视图,允许其直接创建控件 这增加了耦合。。。 2) 在视图上创建一个界面来操作控件 这意味着必须将视图传递(而不是简单地绑定)到viewmodel 3) 创建控件的抽象以绑定到视图,并基于viewmodel创建的抽象进行视图渲染 随着控制集的扩展,这会增加维护噩梦

我建议通过主viewmodel上的属性公开模型(直接或封装在micro viewmodels中),并通过xaml将其绑定到视图上的属性,这样viewmodel上的任何属性更改都会向视图发送更新。使用视图中的模型信息和控件创建逻辑来清除和重新创建控件,并将模型动态绑定到您创建的控件。这将简化控件的创建和绑定,并且您无需练习任何巫术即可将输入控件的信息返回到模型中


请注意,即使您创建了一个中间类(附加的行为、装饰器或其他东西),它仍然需要能够直接访问视图的控件结构,以便将生成的控件附加到可视化树,这可能会导致其他问题。

使用WPF/MVVM时,您的数据层就是您的应用程序(应用程序),您可以使用
模板
等工具来告诉WPF如何将应用程序组件绘制到UI

例如,假设您被赋予了动态呈现一组控件的任务

WinForms的方法可能是在对象之间循环,为每个对象创建一个UI控件,然后将UI控件添加到屏幕上

然而,使用WPF/MVVM,您可以创建一个表示每个对象的类(一个
模型
),并为WPF提供一个要显示的类列表

WPF可以使用许多不同的控件来绘制对象列表,但最基本的控件可能是一个。如果您感兴趣,我有一些简单的
ItemsControl
示例

现在,即使您已经为WPF提供了要渲染的对象列表,并告诉它要使用什么控件来渲染列表,WPF可能仍然不知道如何绘制对象。通常的解决方案是包含某种XAML模板,告诉它如何绘制对象

下面是一个简单的示例模板,用于告诉WPF如何绘制类型为
MyClassObject
的对象:

<DataTemplate DataType="{x:Type local:MyClassObject}">
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="Name:" />
        <TextBox Text="{Binding Name}" />
    </StackPanel>
</DataTemplate>


我希望这能帮助您朝着正确的方向前进:)

您需要“动态”创建什么样的“控件”?您可能需要一个
ItemsControl
。贴一张你需要的截图。你所有的建议都很难看。使用
ItemsControl
。时期为什么要这么做会使事情变得过于复杂?@HighCore如果你有答案,请随时提供。“使用ItemsControl”是模糊的,并且还假设他想要一个控件列表,而不是其他一些布局机制。是的,动态控件创建很难看,特别是在MVVM环境中,我们试图避免使用CodeBehind,尽可能使用绑定。@BahriGundor我无法提供具体的答案,因为OP没有给出具体的问题。这就是我要求澄清的原因。我的观点仍然是,“动态控件创建”在过程winforms(如代码)的意义上在WPF中是完全不需要的。@HighCore为什么不提交一个答案,演示他如何使用ItemsControl,例如,使用类型映射的数据模板,创建viewmodel提供的元素并将其数据绑定到viewmodel?这是一种简单但有效的方法。我只是觉得它在很多方面都很有限。这可能是他所需要的。一如既往,你的贡献是卓越的。我不想自己写一个答案,因为我希望从OP那里得到一些澄清,但很可能你的答案非常适合。谢谢@HighCore:)我同意,这个问题可以再澄清一点,因为很难确切说出想要什么,但希望这能给OP提供足够的信息started@Rachel-你的博客链接对我不起作用。我的浏览器说“•确保网址正确。”当询问浏览器更多信息时,它说远程地址拒绝了连接。大多数(如果不是全部的话)wordpress.com链接对我不起作用-这与我的配置有关吗?@infowant我不知道wordpress是如何配置的,但是我知道对于评论,我可以选择将它们标记为垃圾邮件。也许如果一个IP被标记为垃圾邮件的次数足够多,它就会被阻止?不过这只是一个猜测,你得问问WordPress为什么会阻止你。