Conditional ItemsControl.ItemTemplate binding

2020-04-21 06:03发布

问题:

I'm working on a project and as redundant as it is - I'm trying to do it entirely without code-behind.

I have a User Control called MessagePanel that's meant to wrap messages received through the TCP connection.

Messages can either be text-only or image-only and my control is meant to handle both using different data templates.

Template for texts:

<ItemsControl ItemsSource="{Binding Messages}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock Text="{Binding Name}"/>
                <TextBlock Text="{Binding Text}"/>
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Template for images:

<ItemsControl ItemsSource="{Binding Messages}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <Image Source="{Binding Image}"/>
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

I'm having an issue figuring out how to trigger for either of them to be used based on a IsImage boolean property.

I would appreciate any help.

回答1:

There are several ways to achieve this, and you would typically use a DataTemplateSelector that is assigned to the ItemsControl's Item​Template​Selector property.

You may however write a XAML-only solution with a DataTrigger in the ItemContainerStyle of the ItemsControl:

<ItemsControl ItemsSource="{Binding Messages}">
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="ContentPresenter">
            <Setter Property="ContentTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <StackPanel>
                            <TextBlock Text="{Binding Name}"/>
                            <TextBlock Text="{Binding Text}"/>
                        </StackPanel>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsImage}" Value="True">
                    <Setter Property="ContentTemplate">
                        <Setter.Value>
                            <DataTemplate>
                                <Image Source="{Binding Image}"/>
                            </DataTemplate>
                        </Setter.Value>
                    </Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ItemsControl.ItemContainerStyle>
</ItemsControl>

Note that you might probably not need to have an IsImage property. The DataTrigger could as well check the Image property for null:

<DataTrigger Binding="{Binding Image}" Value="{x:Null}">


标签: c# wpf mvvm