简体   繁体   中英

WPF DataBinding Design issue

so I am having a design issue regarding WPF DataBinding, I have a model :

 public class LightingEffects : ObservableObjectModel
{
    EffectType effectType;
    EffectPropertiesBase properties; 

    public LightingEffects()
    {
        effectType = EffectType.Static;
        properties = this.EffectType == EffectType.Static ? new StaticEffectProperties() : null;
    }

the member variable named properties is of type EffectPropertiesBase from which all other Effectproperties (one of them is StaticEffectProperties as you can see in the code above) classes derive. I assign the derived class instance to the parent variable based on the value of another property name EffectType . Now I want to bind Properties of properties to a control, knowing that it could be of any derived class type, what is the better approach to handle such a scenario ?

There is more than one solution to your problem, you can, for example:

1) Use ContentControl with DataTemplates ( UC_LightingEffect and UC_SomeOtherEffect are UserControls , CurrentEffect is of base ObservableObjectModel type and is a property exposed by your DataContext ):

    <ContentControl Content="{Binding Path=CurrentEffect}"
                    HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch"
                    HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
        <ContentControl.Resources>
            <DataTemplate DataType="{x:Type local:LightingEffect}">
                <local:UC_LightingEffect/>
            </DataTemplate>
            <DataTemplate DataType="{x:Type local:SomeOtherEffect}">
                <local:UC_SomeOtherEffect />
            </DataTemplate>
        </ContentControl.Resources>
    </ContentControl>

2) Select the template using a trigger (if you, for example, use more than one condition to decide which template to use or you use the same template for multiple types)

        <ContentControl Content="{Binding CurrentEffect}"  DataContext="{Binding CurrentEffect}" 
                    HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch"
                    HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
        <ContentControl.Resources>
            <DataTemplate x:Key="templateEmpty">
                <TextBlock Text="Data is null"/>
            </DataTemplate>
            <DataTemplate DataType="{x:Type local:ObservableObjectModel}" x:Key="templateLightingEffects">
                <local:UC_LightingEffects/>
            </DataTemplate>
            <DataTemplate DataType="{x:Type local:ObservableObjectModel}" x:Key="templateOtherEffects">
                <local:UC_SomeOtherEffects />
            </DataTemplate>
        </ContentControl.Resources>
        <ContentControl.Style>
            <Style TargetType="ContentControl">
                <Setter Property="ContentTemplate" Value="{StaticResource templateEmpty}" />
                <Style.Triggers>
                    <DataTrigger Binding="{Binding effectType}" Value ="{x:Static local:EffectType.StaticEffect}">
                        <Setter Property="ContentTemplate" Value="{StaticResource templateLightingEffects}" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding effectType}" Value ="{x:Static local:EffectType.SomeOtherEffect}">
                        <Setter Property="ContentTemplate" Value="{StaticResource templateOtherEffects}" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding effectType}" Value ="{x:Static local:EffectType.YetAnotherEffect}">
                        <Setter Property="ContentTemplate" Value="{StaticResource templateOtherEffects}" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </ContentControl.Style>
    </ContentControl>

As @Akanksha was saying you could use a DataTemplate for every sub type you have (using the DataType property). You can also use a DataTemplateSelector for more complex scenario.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM