【问题标题】:Change ListView CellTemplate based on state of item根据项目的状态更改 ListView CellTemplate
【发布时间】:2011-05-06 06:20:09
【问题描述】:

我有一个 ListView,它有一个 ObservableCollection 作为它的 ItemsSource,它有几个列。其中之一是状态列,根据项目的当前状态,显示不同的消息。目前,这是作为基本字符串实现的,虽然它可以工作,但它远非漂亮或用户友好。我希望能够改变输出类型以更适合项目的状态。

我确实做了一些研究,知道我需要使用 CellTemplate 来影响显示,但是所有不同类型的模板都让我不知所措,以至于我不知道下一步该去哪里。

我的代码(不包括很多其他的列表视图绒毛)如下:

<ListView Name="itemsListView" ItemsSource="{Binding Source={StaticResource listingDataView}}" IsSynchronizedWithCurrentItem="True">
    ...
    <ListView.View>
         <GridView AllowsColumnReorder="true" ColumnHeaderToolTip="Item Information">
             ...
             <GridViewColumn DisplayMemberBinding="{Binding Path=StatusMessage}" Width="283" Header="Status" HeaderContainerStyle="{StaticResource GVHeaderLeftAlignedStyle}" />
         </GridView>
    </ListView.View>
</ListView>

是的,这些项目具有硬编码的“状态消息”,与与代码实际相关的其他属性一起更新,导致我的代码其他地方出现难看的重复。 (是的,我知道这远非漂亮,但我也想改进它。)该属性将被称为ItemState,因为我没有那么有创意。

所以,我的问题是:如何更改此列以针对给定状态进行最合适的显示?文本描述适用于许多状态,但有些相当冗长,可能会从带有进度条的文本中受益,并且可能还有一些剩余时间。另一个州将从拥有可点击的超链接中受益。换句话说,我认为我至少需要 3 个不同的 CellTemplates。

我意识到这是一个相当开放的问题,很大程度上是由于某人(=我)的设计错误造成的,他对 WPF 经验很少,但这正是我希望有经验的人能够让我明白的原因在我把事情弄得比现在更糟之前的一些基本代码。 :)

【问题讨论】:

    标签: c# wpf xaml refactoring celltemplate


    【解决方案1】:

    您可以使用触发器来更改单元格的内容,例如

    <GridViewColumn Header="Status">
        <GridViewColumn.CellTemplate>
            <DataTemplate>
                <ContentControl>
                    <ContentControl.Style>
                        <Style TargetType="{x:Type ContentControl}">
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding StateItem.HasError}" Value="True">
                                    <Setter Property="ContentTemplate">
                                        <Setter.Value>
                                            <!-- Possibly create another contentcontrol which differentiates between errors -->
                                            <DataTemplate>
                                                 <TextBlock Text="{Binding StateItem.Error}"
                                                            Foreground="Red"/>
                                            </DataTemplate>
                                        </Setter.Value>
                                    </Setter>
                                </DataTrigger>
    
                                <DataTrigger Binding="{Binding StateItem.HasError}" Value="False">
                                    <Setter Property="ContentTemplate">
                                        <Setter.Value>
                                            <DataTemplate>
                                                <Image Source="Images/Default.ico"/>
                                            </DataTemplate>
                                        </Setter.Value>
                                    </Setter>
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </ContentControl.Style>
                </ContentControl>
            </DataTemplate>
        </GridViewColumn.CellTemplate>
    </GridViewColumn>
    

    如果你进一步分支,代码会变得有点疯狂,但这是一种方法。

    编辑: setter 应该设置ContentTemplate 而不是Content,否则显然无法创建新控件并且只有一行显示正确的内容,因为内容只能有一个父母。

    【讨论】:

    • 太棒了。我花了一些时间让一切都按我想要的方式工作(尽管我可能还需要弄清楚如何在多个控件中填充内容),但现在我完全有一个进度条在那里。谢谢你的帮助。 :)
    猜你喜欢
    • 1970-01-01
    • 2022-11-15
    • 1970-01-01
    • 1970-01-01
    • 2011-02-06
    • 1970-01-01
    • 2021-12-09
    • 1970-01-01
    • 2023-03-18
    相关资源
    最近更新 更多