根据项目状态更改ListView CellTemplate

时间:2011-05-06 06:20:09

标签: c# wpf xaml refactoring celltemplate

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

我做了一些研究,并且知道我需要使用CellTemplate来影响显示,但是所有不同类型的模板简直让我无法理解我无法找到下一步的位置。

我的代码(不包括许多其他listview绒毛)如下:

<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的经验相当少,但这正是为什么我希望有经验的人可以让我直截了当一些基本代码,然后我做了比我已经更糟糕的事情。 :)

1 个答案:

答案 0 :(得分:5)

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

<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>

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

修改:设置者应设置ContentTemplate而不是Content,否则可能无法创建新控件,并且只有一行显示自内容以来的正确内容只能有一个父母。