Search code examples
wpfenumsnesteddatatemplatedatatrigger

WPF Datatrigger on subproperty not working


I've got a content control and its content template shall change triggered by an data trigger, but the trigger is not firing. What am I doing wrong? The content controls' and Data templates' datacontext is "MainViewModel". Here is the code in question:

Content controls' resources:

<DataTemplate x:Key="TopologyConfigurationInputTemplate">
<ContentControl>
    <ContentControl.Resources>
        <conv:ObjectToStringConverter x:Key="ObjectToStringConverter"/>
    </ContentControl.Resources>
    <ContentControl.Style>
        <Style TargetType="{x:Type ContentControl}">
            <Setter Property="ContentTemplate" Value="{StaticResource CraneTemplate123}"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=TopologyConfigViewModel.TemplateSelection}"
                        Value="{x:Static vm:TopologyConfigViewModel+TemplateSelectionEnum.CRANE}">
                    <Setter Property="ContentTemplate" Value="{StaticResource CraneTemplate123}"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding Path=TopologyConfigViewModel.TemplateSelection}"
                        Value="{x:Static vm:TopologyConfigViewModel+TemplateSelectionEnum.EQUIPMENT}">
                    <Setter Property="ContentTemplate" Value="{StaticResource EquipmentTemplate123}"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding Path=TopologyConfigViewModel.TemplateSelection}"
                        Value="{x:Static vm:TopologyConfigViewModel+TemplateSelectionEnum.TERMINAL}">
                    <Setter Property="ContentTemplate" Value="{StaticResource TerminalTemplate123}"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ContentControl.Style>
</ContentControl>

Content Control:

<ContentControl ContentTemplate="{StaticResource TopologyConfigurationInputTemplate}" MinHeight="250"/>

This is my "MainViewModel":

public class MainViewModel : BaseViewModel
{
    private TopologyViewModel _topologyViewModel;
    private TopologyConfigViewModel _topologyConfigViewModel;
    protected Dictionary<string, List<string>> _validationErrors;

    public MainViewModel()
    {
        _topologyViewModel = new TopologyViewModel(GetTopology());
        _topologyConfigViewModel = new TopologyConfigViewModel(_topologyViewModel);
        _validationErrors = new Dictionary<string, List<string>>();
    }

    public TopologyViewModel TopologyViewModel
    {
        get { return _topologyViewModel; }
        set
        {
            if (_topologyViewModel != value)
            {
                _topologyViewModel = value;
                NotifyPropertyChanged("TopologyViewModel");
            }
        }
    }

    public TopologyConfigViewModel TopologyConfigViewModel
    {
        get { return _topologyConfigViewModel; }
        set
        {
            if (_topologyConfigViewModel != value)
            {
                _topologyConfigViewModel = value;
                NotifyPropertyChanged("TopologyConfigViewModel");
            }
        }
    }
}

This is the nested ViewModel "TopologyConfigViewModel", where the property for the data trigger is implemented:

public class TopologyConfigViewModel : BaseViewModel
{
    public enum TemplateSelectionEnum { CRANE, EQUIPMENT, TERMINAL }
    private TemplateSelectionEnum _templateSelection;
    private TopologyViewModel _topologyViewModel;
    protected Dictionary<string, List<string>> _validationErrors;
    private ICommand _craneConfigSelectCmd;
    private ICommand _equipmentConfigCmd;
    private ICommand _terminalConfigCmd;

    public TopologyConfigViewModel(TopologyViewModel pTopologyViewModel)
    {
        _topologyViewModel = pTopologyViewModel;
        _validationErrors = new Dictionary<string, List<string>>();
        _craneConfigSelectCmd = new DelegateCommand(param => ChangeConfigTemplate(param));
        _equipmentConfigCmd = new DelegateCommand(param => ChangeConfigTemplate(param));
        _terminalConfigCmd = new DelegateCommand(param => ChangeConfigTemplate(param));
    }

    public TemplateSelectionEnum TemplateSelection
    {
        get { return _templateSelection; }
        set
        {
            if (_templateSelection != value)
            {
                _templateSelection = value;
                NotifyPropertyChanged("TemplateSelection");
            }
        }
    }

    public ICommand CraneConfigSelectCmd
    {
        get { return _craneConfigSelectCmd; }
    }

    public ICommand EquipmentConfigSelectCmd
    {
        get { return _equipmentConfigCmd; }
    }

    public ICommand TerminalConfigSelectCmd
    {
        get { return _terminalConfigCmd; }
    }

    public void ChangeConfigTemplate(object param)
    {
        try
        {
            if (param == null)
                return;
            if (((string)param) == "Crane")
                TemplateSelection = TemplateSelectionEnum.CRANE;
            else if (((string)param) == "Equipment")
                TemplateSelection = TemplateSelectionEnum.EQUIPMENT;
            else
                TemplateSelection = TemplateSelectionEnum.TERMINAL;
            //CraneConfigSelected = true;

        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.Message);
        }
    }
}

Following is working correctly: Commands to change enums value, Property changed notifications

Thanks in advance!


Solution

  • It should work if you bind the Content property of the ContentControl to the view model:

    <ContentControl ContentTemplate="{StaticResource TopologyConfigurationInputTemplate}" Content="{Binding}" MinHeight="250"/>