Gopichandar
Gopichandar

Reputation: 2832

Binding issue over the Datatrigger in DataTemplate - WPF

Objective My objective is to load the Control in GridViewrow based on the property in the viewmodel.

Sample Code: Here is the sample xaml which I tried.

<ListView Margin="10" Name="lvUsers">
    <ListView.View>
        <GridView x:Name="gridview">
            <GridViewColumn Header="Type">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <ContentControl>
                            <ContentControl.Style>
                                <Style TargetType="{x:Type ContentControl}">
                                    <Style.Triggers>
                                        <DataTrigger Binding="{Binding IsImage}" Value="True">
                                            <Setter Property="ContentTemplate">
                                                <Setter.Value>                                                        
                                                    <DataTemplate>
                                                        <TextBlock Text="Text goes here"
                                                    Foreground="Red"/>
                                                    </DataTemplate>
                                                </Setter.Value>
                                            </Setter>
                                        </DataTrigger>

                                        <DataTrigger Binding="{Binding IsImage}" Value="False">
                                            <Setter Property="ContentTemplate">
                                                <Setter.Value>
                                                    <DataTemplate>
                                                        <TextBlock Text="{Binding Itemsource}"/>

                                                    </DataTemplate>
                                                </Setter.Value>
                                            </Setter>
                                        </DataTrigger>
                                    </Style.Triggers>
                                </Style>
                            </ContentControl.Style>
                        </ContentControl>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>

        </GridView>
    </ListView.View>
</ListView>

And my sample xaml.cs code

public partial class MainWindow : Window
{    
    public MainWindow()
    {
        InitializeComponent();            
        List<myClass> mc = new List<myClass>();
        mc.Add(new myClass() { Itemsource = "test", IsImage = false });
        mc.Add(new myClass() { Itemsource = "test", IsImage = true });
        lvUsers.ItemsSource = mc;
    }     
}

class myClass
{
    public string Itemsource { get; set; }
    public bool IsImage { get; set; }
}

Issue: DataTriggers are working as expected but the binding inside the Triggers is giving me Empty

<TextBlock Text="{Binding Itemsource}"/>

I am expecting the above line to display test in the respective row but it displaying Empty row.

Upvotes: 1

Views: 1815

Answers (1)

Carbine
Carbine

Reputation: 7903

Couldn't figure out why the TextBlock's DataContext is null. Its probably due to the custom content template. But any how you can fix this by searching for the ContentControl ancestor type like this.

<DataTrigger Binding="{Binding IsImage}" Value="False">
    <Setter Property="ContentTemplate">
        <Setter.Value>
            <DataTemplate>
                <TextBlock Text="{Binding DataContext.Itemsource, RelativeSource={RelativeSource FindAncestor, AncestorType=ContentControl}}"/>
            </DataTemplate>
        </Setter.Value>
    </Setter>
</DataTrigger>

This will fetch the data from the parent controls data binding.

Edit

It's because of ContentControl, you need to do content binding like - <ContentControl Content="{Binding}">. Then data context will be available as it is and <TextBlock Text="{Binding Itemsource}"/> will work.

<ContentControl Content="{Binding}">
    <ContentControl.Style>
        <Style TargetType="{x:Type ContentControl}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsImage}" Value="True">
                    <Setter Property="ContentTemplate">
                        <Setter.Value>                                                        
                            <DataTemplate>
                                <TextBlock Text="Text goes here"
                            Foreground="Red"/>
                            </DataTemplate>
                        </Setter.Value>
                    </Setter>
                </DataTrigger>

                <DataTrigger Binding="{Binding IsImage}" Value="False">
                    <Setter Property="ContentTemplate">
                        <Setter.Value>
                            <DataTemplate>
                                <TextBlock Text="{Binding Itemsource}"/>

                            </DataTemplate>
                        </Setter.Value>
                    </Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ContentControl.Style>
</ContentControl>

Upvotes: 2

Related Questions