Search code examples
c#wpfdatatemplatedatatrigger

Binding in DataTrigger seems not working


I have a ComboBox which should have a text when nothing is selected. This seems like a straight forward problem, and has many answers on the net, but unfortunately, it is not working for me. I think, the reason is, that I don't want to show a static text, but rather a bound text.

My minimal not working example looks like this:

public class Model
{
    public string Name { get; set; }

    public SubModel SelectedItem { get; set; }

    public List<SubModel> Items { get; set; }
}

public class SubModel
{
    public string Description { get; set; }
}

and the MainWindow:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        var selectedSubModel = new SubModel { Description = "SubModel5" };
        var model1 = new Model
        {
            Name = "Model1",
            Items = new List<SubModel>
                {
                    new SubModel { Description = "SubModel1" },
                    new SubModel { Description = "SubModel2" },
                    new SubModel { Description = "SubModel3" }
                }
        };
        var model2 = new Model
        {
            Name = "Model2",
            SelectedItem = selectedSubModel,
            Items = new List<SubModel>
                {
                    new SubModel { Description = "SubModel4" },
                    selectedSubModel,
                    new SubModel { Description = "SubModel6" }
                }
        };
        var model3 = new Model
        {
            Name = "Model3",
            Items = new List<SubModel>
                {
                    new SubModel { Description = "SubModel7" },
                    new SubModel { Description = "SubModel8" },
                    new SubModel { Description = "SubModel9" }
                }
        };

        _itemsControl.Items.Add(model1);
        _itemsControl.Items.Add(model2);
        _itemsControl.Items.Add(model3);
    }
}

with xaml:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:WpfApplication1="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="350" Width="525">
    <ItemsControl x:Name="_itemsControl">
        <ItemsControl.ItemTemplate>
            <DataTemplate DataType="WpfApplication1:Model">
                <ComboBox ItemsSource="{Binding Items}"
                        SelectedItem="{Binding SelectedItem}">
                    <ComboBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Description}"></TextBlock>
                        </DataTemplate>
                    </ComboBox.ItemTemplate>
                    <ComboBox.Style>
                        <Style TargetType="ComboBox">
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding SelectedItem}" Value="{x:Null}">
                                    <Setter Property="Background">
                                        <Setter.Value>
                                            <VisualBrush>
                                                <VisualBrush.Visual>
                                                    <TextBlock Text="{Binding Name}"/>
                                                </VisualBrush.Visual>
                                            </VisualBrush>
                                        </Setter.Value>
                                    </Setter>
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </ComboBox.Style>
                </ComboBox>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Window>

This gives the follwing: Not expected result

But it should look similar to this: enter image description here


Solution

  • The answer is, to put the visual brush in the resources of the combobox:

    <DataTemplate DataType="WpfApplication1:Model">
        <ComboBox ItemsSource="{Binding Items}"
                SelectedItem="{Binding SelectedItem}">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Description}"></TextBlock>
                </DataTemplate>
            </ComboBox.ItemTemplate>
            <ComboBox.Resources>
                <VisualBrush x:Key="_myBrush">
                    <VisualBrush.Visual>
                        <TextBlock Text="{Binding Name}"/>
                    </VisualBrush.Visual>
                </VisualBrush>
            </ComboBox.Resources>
            <ComboBox.Style>
                <Style TargetType="ComboBox">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding SelectedItem}" Value="{x:Null}">
                            <Setter Property="Background" Value="{StaticResource _myBrush}"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ComboBox.Style>
        </ComboBox>
    </DataTemplate>
    

    Then, together with the rest of the code, it works like expected.