wpf 基于枚举为数据模板选择用户控件

r7xajy2e  于 2023-05-01  发布在  其他
关注(0)|答案(2)|浏览(162)

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

q3aa0525

q3aa05251#

您可以使用自定义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创建自定义模板选择器的示例,从上述数据模板初始化其两个DataTemplate属性:

<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>

(In真实的生活中,设置ItemsSource,而不是像我一样声明内联项。)
完整性:要访问你的C#类,你需要设置命名空间,e.例如,在一个实施例中,

xmlns:local="clr-namespace:WPF"
qybjjes1

qybjjes12#

另一个可能的快速解决方案是使用Data Trigger:

<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之类的东西。

相关问题