MVVM - 我应该在哪里放置动态生成和加载XAML的代码?

时间:2009-07-18 17:04:21

标签: wpf xaml dynamic mvvm

我想这是一个哲学问题,但我有一些代码可以动态地将模板化列添加到GridView,方法是在运行时从Model数据生成XAML并使用XamlReader加载它。我的问题是,在MVVM世界中,我应该在哪里放置完成此操作的代码?目前,我已经在代码隐藏中使用了它,但我正在考虑是否应将其移至ViewModel。

5 个答案:

答案 0 :(得分:2)

WPF / Silverlight开发人员圈子有一个很大的变化,转向MVVM架构的解决方案,但是他们不会比简单或一般的例子更进一步。 这在简单的应用程序中不是什么大问题。当你考虑时,它会变得严肃。

  • 动态构建的屏幕或页面,可能是为了响应用户操作
  • 由...组成的复合页​​面 持有视图的区域,也许是嵌套的 视图,每个都实现为MVVP 三单元组
  • 关闭一个集合的向导 单击视图

这里有重要的逻辑。它去哪儿了?

正是这个(你的问题),我得到了挂机将我的东西移动到MVVM,我读了一篇很好的文章给了我一些啊哈时刻,这种架构适合更大的一个类,其中一些类正在组成生命周期MVVM三重奏

如果您想阅读完整的文章here Ward Bell gos更详细。 可能这只是大局中的一小部分,另一篇很棒的文章讨论了复合应用程序邻域中的主要参与者,请参阅here

这与你的问题有什么关系?那么我相信ViewModel代表了视图,你的视图是在运行时决定的,所以如果问题需要有动态生成的列,那么创建渲染视图和适合你的视图模型可能是其他东西的责任。最终结果和实例。

答案 1 :(得分:1)

再考虑一下这个问题,我想我对自己的问题有了答案,但我很乐意反馈,因为我对此仍然很陌生。

通常,View只知道ViewModel中的属性,而ViewModel提供View将绑定但不真正了解View的任何窗口小部件/ UI元素的数据。所以,我的想法是我应该把这段代码留在代码隐藏中。代码引用DataContext中的属性(设置为ViewModel),挂钩到可视树中,并动态地向树中添加更多分支和叶子。当我这样说的时候,它突然听起来对我非常“看”:)

答案 2 :(得分:0)

我不认为生成XAML并使用XamlReader处理它是个好主意。

你为什么要那样做?

如果您希望视图依赖于数据类型或某些条件,则可以通过DataTemplate实现。 DataType属性使其按类型选择模板。触发器和随附的ContentControl可以根据数据条件交换模板。

我要将实际的XAML存储在数据库中,这完全是与MVVM无关的其他故事。它有许多潜在的问题,如性能,XamlReader语法限制,汇编/资源解析怪癖,安全性等等。

答案 3 :(得分:0)

现在问题有点澄清,再试一次。

首先,图表可能更好地由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只是字符串,然后由触发器处理。

答案 4 :(得分:0)

我使用MVVM原则获得了一个有效的解决方案,并且很少有代码支持,希望它有所帮助:My Solution