在子元素更改时更改ListView.ItemTemplate [英] Change ListView.ItemTemplate on subelement change

查看:100
本文介绍了在子元素更改时更改ListView.ItemTemplate的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我们有简单的数据类:

let's say we have simple data class:

public class Ex {
    public string Prop1 {...} // notify property
    public string Prop2 {...} // notify property
}

和此类的ObservableCollection对象.我想让此集合显示在由Ex.Prop2区分的单独DataTemplated的ListView中(如果为null或为空,则使用template01,否则使用template02).可以在运行时更改此属性,以使使用ListView.ItemTemplateSelector进行的简单技巧"不起作用:(

and an ObservableCollection of objects of this class. I want to have this collection displayed in a ListView with seperated DataTemplated which is distinguished by Ex.Prop2 (if it is null or empty then template01 is used, otherwise template02). This property can be changed in runtime so simple "trick" with ListView.ItemTemplateSelector does not work :(

如何实现此功能?除了在集合的每个对象上侦听NotifyPropertyChanged以及手动更改模板之外,还有其他方法可以实现吗?

How to achieve this functionality? Is it possible to achieve it any other way than listening to NotifyPropertyChanged on each object of the collection and than changing manually the template?

感谢您的帮助.

下面我已经拥有的代码:

Below piece of code which I already have:

<ListView x:Name="lstTerms"
    ItemsSource="{Binding Game.Words}"
    HorizontalContentAlignment="Stretch"
    Grid.IsSharedSizeScope="True">
    <ListView.ItemContainerStyle>
        <Style>
            <Setter Property="Control.Padding" Value="0" />
        </Style>
    </ListView.ItemContainerStyle>

    <!-- checks if element is null or its Prop2 is null or empty. If so, uses NullTemplate -->
    <ListView.ItemTemplateSelector>
        <local:MySelectTemplate
            NormalTemplate="{StaticResource NormalItemTemplate}"
            NullTemplate="{StaticResource NullItemTemplate}" />
    </ListView.ItemTemplateSelector>
</ListView>

推荐答案

您可以使用一个包含两个Grid的DataTemplate来代替单个TemplateSelector,该Grid可以根据属性值切换可见性.

Instead of using a TemplateSelector, you can have a single DataTemplate containing two Grids, which switch visibility dependent on the property values.

这里是一个例子:

<ListView.ItemTemplate>
    <DataTemplate>
        <Grid>
            <Grid Background="LightBlue" Name="normalGrid">
                <Grid.Style>
                    <Style>
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding Path=Prop1}" Value="{x:Null}">
                                <Setter Property="Grid.Visibility" Value="Hidden"></Setter>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </Grid.Style>
                <TextBlock Text="{Binding Prop1}"></TextBlock>
            </Grid>
            <Grid Background="Green" Name="nullGrid">
                <Grid.Style>
                    <Style>
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding ElementName=normalGrid, Path=Visibility}" Value="Visible">
                                <Setter Property="Grid.Visibility" Value="Hidden"></Setter>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </Grid.Style>
                <TextBlock Text="{Binding Prop2}"></TextBlock>
            </Grid>
        </Grid>
    </DataTemplate>
</ListView.ItemTemplate>

很明显,您可以用代表两个数据模板的UserControls替换TextBlock元素.

Obviously you could replace the TextBlock elements with UserControls representing your two DataTemplates.

如果需要,还可以通过将Grid.Visibility绑定到ViewModel上的属性(例如,名为IsVisible)并使用VisibilityConverter来消除对庞大样式的需要.

If you want, you can also remove the need for the bulky Styles by binding Grid.Visibility to a property (named, for example, IsVisible) on your ViewModel and using a VisibilityConverter.

这篇关于在子元素更改时更改ListView.ItemTemplate的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆