【问题标题】:Selecting User Control for Data Template based on an Enum基于枚举为数据模板选择用户控件
【发布时间】:2016-02-01 21:45:49
【问题描述】:

我正在开发一个 WPF 应用程序,目前我有一个 ItemsControl 绑定到我的视图模型 ObservableCollection 并且我有一个 DataTemplate 使用 UserControl 来呈现 canvas 上的项目。您可以使用多个用户控件,然后根据Enum 切换使用哪一个吗?另一种查看方式是基于EnumObservableCollection 中的项目创建ButtonTextBox

【问题讨论】:

  • 我是否正确理解您想根据Enum 值而不是ViewModel 更改您的UserControl

标签: wpf data-binding datatemplate


【解决方案1】:

您可以使用自定义DataTemplateSelector 为项目选择数据模板。假设我们有以下内容:

public enum Kind
{
    Button, TextBox,
}

public class Data
{
    public Kind Kind { get; set; }
    public string Value { get; set; }
}

您的数据模板选择器可能如下所示:

public class MyTemplateSelector : DataTemplateSelector
{
    public DataTemplate ButtonTemplate { get; set; }

    public DataTemplate TextBoxTemplate { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        Data data = (Data)item;
        switch (data.Kind)
        {
            case Kind.Button:
                return ButtonTemplate;
            case Kind.TextBox:
                return TextBoxTemplate;
        }

        return base.SelectTemplate(item, container);
    }
}

在 XAML 中,为您想要涵盖的所有情况声明模板,在本例中为按钮和文本框:

<Window.Resources>
    <ResourceDictionary>
        <DataTemplate x:Key="ButtonTemplate" DataType="local:Data">
            <Button Content="{Binding Value}" />
        </DataTemplate>
        <DataTemplate x:Key="TextBoxTemplate" DataType="local:Data">
            <TextBox Text="{Binding Value}" />
        </DataTemplate>
    </ResourceDictionary>
</Window.Resources>

最后,让您的 ItemsControl 创建您的自定义模板选择器的实例,并从上述数据模板初始化它的两个 DataTemplateproperties:

<ItemsControl>
    <ItemsControl.ItemTemplateSelector>
        <local:MyTemplateSelector
            ButtonTemplate="{StaticResource ButtonTemplate}"
            TextBoxTemplate="{StaticResource TextBoxTemplate}"/>
    </ItemsControl.ItemTemplateSelector>
    <ItemsControl.Items>
        <local:Data Kind="Button" Value="1. Button" />
        <local:Data Kind="TextBox" Value="2. TextBox" />
        <local:Data Kind="TextBox" Value="3. TextBox" />
        <local:Data Kind="Button" Value="4. Button" />
    </ItemsControl.Items>
</ItemsControl>

(在现实生活中,设置 ItemsSource 而不是像我一样声明内联项目。)

为了完整性:要访问您的 C# 类,您需要设置命名空间,例如,

xmlns:local="clr-namespace:WPF"

【讨论】:

  • 很棒的反应真的很有帮助。我已经让它与 UserControls 一起工作,这是我的最终目标,非常感谢。
【解决方案2】:

另一个可能的快速解决方案是使用数据触发器:

        <ContentControl>
            <ContentControl.Style>
                <Style TargetType="ContentControl">
                    <Setter Property="Content"
                            Value="{StaticResource YourDefaultLayout}" />
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding YourEnumVMProperty}"
                                     Value="{x:Static local:YourEnum.EnumValue1}">
                            <Setter Property="Content"
                                    Value="{StaticResource ContentForEnumValue1}" />
                        </DataTrigger>
                        <DataTrigger Binding="{Binding YourEnumVMProperty}"
                                     Value="{x:Static local:YourEnum.EnumValue2}">
                            <Setter Property="Content"
                                    Value="{StaticResource ContentForEnumValue2}" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ContentControl.Style>
        </ContentControl>

您还可以使用触发器设置器定义整个控件的模板。

我更喜欢这个,因为不需要定义所有的 DataTemplateSelector 等。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多