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.