【问题标题】:Q: How should I handle Datatemplates for Models?问:我应该如何处理模型的数据模板?
【发布时间】:2021-10-30 01:35:12
【问题描述】:

在 MVVM 模式中,视图不应该知道模型的任何信息,但是如果我想以不同的方式显示不同的类型怎么办?

例如,我有两个班级。类Message和继承自Message的AttachmentMessage类。

留言

public class Message
{
    public string Content { get; set; }
}

附件消息

public class AttachmentMessage : Message
{
    public string Filename { get; set; }
}

现在,当我在ObservableCollection<Message> 中使用它们时,我在这个集合中都有两个模型,但我无法告诉 WPF 它必须使用哪个数据模板,不知道有哪些模型。

那么有什么办法可以解决这个问题呢?

【问题讨论】:

    标签: c# wpf mvvm


    【解决方案1】:

    最常见和推荐的方法是为您需要的每种类型创建一个数据模板并将其放入您的资源中。 以下代码假定您的可观察集合的名称为 Messages。 示例:

    <ItemsControl ItemsSource="{Binding Messages}">
        <ItemsControl.Resources>
            <DataTemplate DataType="{x:Type local:Message}">
                <TextBlock Text="{Binding Content}"/>
            </DataTemplate>
            <DataTemplate DataType="{x:Type local:AttachmentMessage}">
                <TextBlock Text="{Binding Filename}"/>
            </DataTemplate>
        </ItemsControl.Resources>
    </ItemsControl>
    

    另一种方法是创建一个DataTemplateSelector。假设您的消息都具有表明其优先级的属性。您可以创建一个模板选择器,如下所示。 DataTemplateSelector 可以在您需要更细粒度地控制所选模板时使用。

    public class MyDataTemplateSelector : DataTemplateSelector
    {
        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            if (item is Message m && container is FrameworkElement fm)
            {
                if (m.Priority == Priority.High)
                {
                    return fm.FindResource("HighPriorityTemplate") as DataTemplate;
                }
                else
                {
                    return fm.FindResource("NormalPriorityTemplate") as DataTemplate;
                }
            }
    
            return null;
        }
    }
    

    并在 xaml 中使用它,如下所示:

    <Window.Resources>
        <!-- Put your templates here-->
        <local:MyDataTemplateSelector x:Key="MyDataTemplateSelector"/>
    </Window.Resources>
    <ItemsControl ItemsSource="{Binding Messages}" ItemTemplateSelector="{StaticResource MyDataTemplateSelector}">
    

    正如我的旁注,在 MVVM 模式中,通常有三个部分,ModelViewViewModel。有些人采取直接绑定到Model 的快捷方式,但我通常会避免这种情况。你可以找到关于这个here的讨论。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-02
      相关资源
      最近更新 更多