Wpf MVVM—我应该将动态生成和加载XAML的代码放在哪里?
我想这是一个哲学问题,但我有一些代码,通过在运行时从模型数据生成XAML并使用XamlReader加载,动态地将模板列添加到GridView。我的问题是,在MVVM世界中,我应该把实现这一点的代码放在哪里?目前,我在代码隐藏中有它,但我正在考虑是否应该将它移到ViewModel。再考虑一下,我想我对自己的问题有一个答案,但我希望您的反馈,因为我对这个问题还是很陌生Wpf MVVM—我应该将动态生成和加载XAML的代码放在哪里?,wpf,xaml,dynamic,mvvm,Wpf,Xaml,Dynamic,Mvvm,我想这是一个哲学问题,但我有一些代码,通过在运行时从模型数据生成XAML并使用XamlReader加载,动态地将模板列添加到GridView。我的问题是,在MVVM世界中,我应该把实现这一点的代码放在哪里?目前,我在代码隐藏中有它,但我正在考虑是否应该将它移到ViewModel。再考虑一下,我想我对自己的问题有一个答案,但我希望您的反馈,因为我对这个问题还是很陌生 通常,视图只知道ViewModel内部的属性,而ViewModel提供视图将绑定到的数据,但并不真正知道视图的任何小部件/UI元素。
通常,视图只知道ViewModel内部的属性,而ViewModel提供视图将绑定到的数据,但并不真正知道视图的任何小部件/UI元素。所以,我的想法是,我应该把这个代码放在代码后面。代码引用DataContext(设置为ViewModel)中的属性,钩住可视化树,并动态地向树添加更多分支和叶子。当我这么说的时候,我突然觉得它很“视图”:在WPF/Silverlight开发者圈子里,有一个很大的运动,就是转向一个MVVM架构的解决方案,但是他们没有比简单或一般的例子更进一步。 在简单的应用程序中,这不是什么大问题。当你沉思时,它会变得严重
- 动态构造的屏幕或页面,可能是为了响应用户操作
- 由以下内容组成的复合页: 包含视图(可能是嵌套视图)的区域 视图,每个视图都实现为MVVP 三合会
- 向导正在关闭一个 只需单击即可查看
这一切与你的问题有什么关系?我认为ViewModel代表视图,您的视图是在运行时确定的,因此,如果问题需要动态生成列,则可能是其他人负责创建渲染视图和适合最终结果的适当viewmodel并对其进行实例处理。我认为生成XAML并使用XamlReader进行处理不是一个好主意 你为什么要做那件事 如果您希望视图依赖于数据类型或特定条件,则可以通过DataTemplate实现。DataType属性使其按类型选择模板。触发器和封闭的ContentControl可以根据数据条件交换模板
我认为你们准备在数据库中存储实际的XAML,这完全是另一回事,与MVVM无关。它有很多潜在的问题,比如性能、XamlReader语法限制、程序集/资源解析怪癖、安全性等等。现在问题已经澄清了,下面再做一次尝试 首先,WPF工具箱中的WPF图表控件可能更好地处理图表,它们在其中添加了非常有趣的内容。我绝对建议在创建自定义的基于ListView的图表之前尝试一下 但无论如何,回到你澄清的问题上来。在这里,您应该使用DataTemplateSelector,或者使用设置模板的自定义IValueConverter触发 DataTemplateSelector的发明正是出于这个原因,但实际上它有点混乱。您需要处理从资源中加载模板的问题,这比XamlReader好一点 有了IValueConverter,情况会是这样:
<DataTemplate>
<ContentControl x:Name="content" Content="{Binding}">
</ContentControl>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Converter={local:TemplateChoseConverter}}" Value="SystemType">
<Setter TargetName="content" Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="[system type] "/>
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Converter={local:TemplateChoseConverter}}" Value="Action">
<Setter TargetName="content" Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Button Text="[action] "/>
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
在这里,您将ContentControl放在DataTemplate中,并根据在IValueConverter中计算的内容在DataTemplate中触发交换内部嵌套模板
这样,您就永远不会处理XAML,即使您选择ValueConverter的模板也只会生成字符串,然后由触发器进行处理。我得到了一个使用MVVM原则和少量代码的有效解决方案,希望它能帮到您:@Ori,谢谢您的回答。沃德钟楼很吸引人,后面的内容也很吸引人()。关于MMVM,社区还有很多事情要弄清楚。至于我的特殊问题,分离生成独立列的代码肯定是有意义的。我可以看到将代码放在自己的类中,然后使用我的ScreenFactory实例化并运行它。(我实际上还没有任何屏幕工厂,但我一直在考虑如何处理快速扩展的app.cs文件——现在我有了一个计划:))同意屏幕工厂很有意义,因为屏幕和视图之间的差异还没有定论。我正试着使用GridView来显示透视表。设计时不知道列数(取决于数据库中存储的数据)。每个列的DataTemplate都不同(每个列绑定到不同的数据)。您将如何使用纯XAML进行设置?如果可能的话,我当然更愿意这样做。(请参阅代码示例)这需要单独的答案,因为注释很短。感谢您的回答,但我不知道有多少列是联合国的