WPF中的条件列表itemtemplate或datatemplate

WPF中的条件列表itemtemplate或datatemplate,wpf,view,Wpf,View,这可能是一个显而易见的问题,但我认为可能有多种方法来实现它,因此这不仅对我有用,而且希望对其他人有用 本质上,我正在寻找实现列表视图的最佳方法,该视图可以接受不同类型的对象,然后使用该对象的适当项/数据模板呈现它们 比如说。。。我们有一个标准的产品列表视图,当我们查看不同的类别时,业务部门决定为每个不同的类别显示不同的项目模板样式 在这里提出这个问题的主要原因是为了避免令人讨厌的黑客解决方案,而是找到一个好的干净方法 希望我已经提供了足够的信息,如果您需要更多信息,请告诉我。只需在参考资料中指定

这可能是一个显而易见的问题,但我认为可能有多种方法来实现它,因此这不仅对我有用,而且希望对其他人有用

本质上,我正在寻找实现列表视图的最佳方法,该视图可以接受不同类型的对象,然后使用该对象的适当项/数据模板呈现它们

比如说。。。我们有一个标准的产品列表视图,当我们查看不同的类别时,业务部门决定为每个不同的类别显示不同的项目模板样式

在这里提出这个问题的主要原因是为了避免令人讨厌的黑客解决方案,而是找到一个好的干净方法


希望我已经提供了足够的信息,如果您需要更多信息,请告诉我。

只需在
参考资料中指定
数据模板
,就足够了,例如

<ListView ItemsSource="{Binding Data}">
    <ListView.Resources>
        <!-- Do NOT set the x:Key -->
        <DataTemplate DataType="{x:Type local:Employee}">
            <TextBlock Text="{Binding Name}" Foreground="Blue"/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type local:Machine}">
            <TextBlock Text="{Binding Model}" Foreground="Red"/>
        </DataTemplate>
    </ListView.Resources>
</ListView>
一个选项是在代码中创建一个:

public class QueueDisplayDataTemplateSelector : DataTemplateSelector
{
    public override DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container)
    {

        var listBoxItem = item as JobQueueListBoxItem;
        var resourceName = String.Empty;
        switch (listBoxItem.JobQueueListBoxItemType)
        {
            case JobQueueListBoxItemType.QueuedJob :
                resourceName = "DataTemplateQueuedJob";
                break;
            case JobQueueListBoxItemType.TransferWorker :
                resourceName = "DataTemplateTransferWorker";
                break;
            default:
                throw new InvalidOperationException(string.Format("There is no corresponding list box template for {0}", listBoxItem.JobQueueListBoxItemType));
        }
        var element = container as FrameworkElement;
        return element.FindResource(resourceName) as DataTemplate;
    }
}
然后在XAML中将其声明为资源

        <ResourceDictionary>
            <local:QueueDisplayDataTemplateSelector x:Key="QueueDisplayDataTemplateSelector" />

然后您会将此分配给您的列表框:

    <ListBox ItemsSource="{Binding ListBoxContents}" 
             ItemTemplateSelector="{StaticResource QueueDisplayDataTemplateSelector}"
             >


谢谢,太好了。如果你有一大堆不同的东西,你能想出一种方法让它更干净吗?你是什么意思?什么是“不干净”?如果您有非常多的项,那么您的模板中将有一个非常大的DataTemplate节点列表,我想知道是否有策略来管理此维护问题。(不要太担心,这是我的假设,我要求以后参考)您可能会将其拆分并重构为各种ResourceDictionary,并在某个时候合并它们,但是我以前没有遇到过这样的问题,所以我不能给你任何明确的建议。作为复制并修改的代码根本不显示任何内容(只有空的ListView)。是的,这可能就是我攻击它的方式,我认为
x:type
更干净,两者都有一点受到大量替代项的影响。这不一定是攻击,
DataTemplateSelector
是一个“适当”的属性,这是有原因的,如果仅根据类型进行区分,那么这是多余的,但使用选择器,您可以将不同的模板应用于相同类型的对象。例如,为了证明使用“hack”一词的合理性,我之所以这么说,是因为使用了
case
而不是使用多态性来管理模板选择。我怀疑WPF的内部机制除了查看类型和从字典中获取相应的数据模板之外,还能做什么,毕竟,没有继承的方法附加到数据对象,而这些数据对象可以提供它。这没什么不同,但我想它的出错空间较小。
    <ListBox ItemsSource="{Binding ListBoxContents}" 
             ItemTemplateSelector="{StaticResource QueueDisplayDataTemplateSelector}"
             >