c# - 如何根据值选择ItemTemplate?

标签 c# wpf

我有一个要在 ItemsControl 中显示的对象集合,根据每个对象中的值,我想显示不同的 ItemTemplate/DataTemplate。我知道您可以使用不同的对象类型来执行此操作,但是否可以基于值来执行此操作?

public class MyItem {
    public int MyValue { get; set; }
}

public ObservableCollection<MyItem> MyItems { get; set; }

<ItemsControl ItemsSource="{Binding Path=MyItems}">

<!--If MyValue == 1-->
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Grid>
                <TextBox/>
            </Grid>
        </DataTemplate>
    </ItemsControl.ItemTemplate>

<!--If MyValue == 2-->
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Grid>
                <CheckBox/>
            </Grid>
        </DataTemplate>
    </ItemsControl.ItemTemplate>

<!--If MyValue == 3-->
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Grid>
                <ComboBox/>
            </Grid>
        </DataTemplate>
    </ItemsControl.ItemTemplate>

</ItemsControl>

最佳答案

首先,如果您可以只使用 Style 触发器(如 Neil B 的回答),那就去做吧。如果您的值(value)更复杂,您可能需要另一种选择......

当您有复杂的值来切换模板时,您可以使用 DataTemplateSelector。这会增加一些开销/复杂性,但会增加您的选择。

public class MyDataTemplateSelector : DataTemplateSelector
{
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        FrameworkElement element = container as FrameworkElement;

        if (element != null && item != null && item is MyItem myItem)
        {
            switch (myItem.MyValue)
            {
                case 1:
                    return element.FindResource("TextBoxResource") as DataTemplate;
                case 2:
                    return element.FindResource("CheckBoxResource") as DataTemplate;
                case 3:
                    return element.FindResource("ComboBoxResource") as DataTemplate;
            }
        }

        return null; // or provide a default template
    }
}

然后在您的 XAML 中:

<App.Resources>
    <!-- these resources can be in any context such as app, window, or user control, they just need to be in scope -->
    <DataTemplate x:Key="TextBoxResource">
        <Grid>
            <TextBox/>
        </Grid>
    </DataTemplate>

    <DataTemplate x:Key="CheckBoxResource">
        <Grid>
            <CheckBox/>
        </Grid>
    </DataTemplate>

    <DataTemplate x:Key="ComboBoxResource">
        <Grid>
            <ComboBox/>
        </Grid>
    </DataTemplate>

    <MyDataTemplateSelector x:Key="myDataTemplateSelector"/>
</App.Resources>

<ItemsControl ItemsSource="{Binding Path=MyItems}"
              ItemTemplateSelector="{StaticResource myDataTemplateSelector}">
</ItemsControl>

然后数据模板选择器显式选择要提供给 ItemsControl 的 DataTemplate,ItemsControl 的 ItemTemplateSelector 属性与 ItemTemplate 属性互斥(不能同时设置)。

关于c# - 如何根据值选择ItemTemplate?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56067660/

相关文章:

.net - 加载 View 模型在缓存 MVVM 灯中找不到 IDataErrorInfo 类型

C# 相当于 VB6 字符占位符

c# - 将 wait.until 与 selenium 一起使用时如何记录超时时间?

c# - Log4Net 单独的配置文件不起作用

c# - 如何在 Jetbrains Rider 中自动重新排列代码?

c# - 如何从 StreamGeometry 中提取 Point 对象?

c# - 一个低开销的文件写入过程应该在它自己的线程上吗?

c# - WCF 3.5 与 4.0 RESTful 服务性能对比

c# - 出于屏幕阅读器的目的覆盖控件的名称

c# - ItemsControl 中元素的 TranslateZoomRotateBehavior?