在列表视图中对单个单元格进行样式化

本文关键字:样式 单元格 单个 列表 视图 | 更新日期: 2023-09-27 17:53:56

我在网上发现了许多在listview中对完整列或完整行进行样式化的例子。

我需要能够动态地样式单个单元格在列表视图。如何访问一行中单个项目的属性?

在列表视图中对单个单元格进行样式化

如果您希望在数据对象中使用有限数量的属性来设置项的样式,则可以创建数据模板和样式,并使用数据触发器在它们之间切换。我已经使用了类似的东西来改变列表中数据对象的外观,基于它们是"活动的还是非活动的",并根据对象是否被选中来创建对象的折叠/展开版本。

您还可以使用转换器(内置或自定义)轻松获得一些效果。例如,我使用内置的布尔到可见性转换器来隐藏/取消隐藏组合框/文本块在我的TaskSelectedTemplate基于对象的IsActive成员。

<DataTemplate x:Key="TaskSelectedTemplate">
    <Grid Margin="4">
        ...
        <Border Grid.Row="0" Grid.Column="0" Grid.RowSpan="4" Margin="0 0 4 0"
                BorderThickness="0" 
                CornerRadius="2">
            <Border.Background>
                <MultiBinding Converter="{StaticResource ActiveToColor}">
                    <Binding Path="."/>
                    <Binding Path="IsActive"/>
                    <Binding Path="IsPaused"/>
                </MultiBinding>
            </Border.Background>
        </Border>
        <StackPanel Grid.Row="0" Grid.Column="1"
                    Orientation="Horizontal"
                    Margin="0 2">
            <ComboBox ItemsSource="{Binding Source={StaticResource TaskTypes}}"
                      SelectedItem="{Binding Type}"
                      Text="{Binding Type}"
                      Visibility="{Binding IsActive, Converter={StaticResource BoolToVis}}"/>
            <TextBlock Text="{Binding Type}"
                       FontWeight="Bold"
                       Visibility="{Binding IsActive, Converter={StaticResource InvBoolToVis}}"/>
            <TextBlock Text=" task"/>
        </StackPanel>
        ...
    </Grid>
</DataTemplate>
<DataTemplate x:Key="TaskNotSelectedTemplate">
    <Grid Margin="4">
        ...
        <Border Grid.Row="0" Grid.Column="0" Grid.RowSpan="4" Margin="0 0 4 0"
                BorderThickness="0" 
                CornerRadius="2">
            <Border.Background>
                <MultiBinding Converter="{StaticResource ActiveToColor}">
                    <Binding Path="."/>
                    <Binding Path="IsActive"/>
                    <Binding Path="IsPaused"/>
                </MultiBinding>
            </Border.Background>
        </Border>
        <TextBlock Grid.Row="0" Grid.Column="1"
                   Text="{Binding Type}"/>
        <TextBlock Grid.Row="0" Grid.Column="2"
                   TextAlignment="Right">
                <Run Text="{Binding Length.TotalMinutes, StringFormat='0', Mode=OneWay}"/>
                <Run Text=" min"/>
            </TextBlock>
        <TextBlock Grid.Row="0" Grid.Column="3"
                   TextAlignment="Right">
                <Run Text="{Binding TimesPerformed, Mode=OneWay}"/>
                <Run Text=" tasks"/>
            </TextBlock>            
    </Grid>
</DataTemplate>
<Style x:Key="ContainerStyle" TargetType="{x:Type ListBoxItem}">
    <!--this part changes the selected item highlight color-->
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ListBoxItem}">
                <Border Name="Border">
                    <ContentPresenter />
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsSelected" Value="true">
                        <Setter TargetName="Border" 
                                Property="Background" Value="#2000BFFF">
                        </Setter>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <!--this part causes selected task to expand-->
    <Setter Property="ContentTemplate" Value="{StaticResource TaskNotSelectedTemplate}"/>
    <Style.Triggers>
        <Trigger Property="IsSelected" Value="True">
            <Setter Property="ContentTemplate" Value="{StaticResource TaskSelectedTemplate}"/>
        </Trigger>
    </Style.Triggers>
</Style>

对于更复杂的场景,您可能需要查看DataTemplateSelector。我从未使用过它,但如果您有很多数据模板要处理,它似乎是理想的。

一般来说,您不需要这个。假设您正在使用GridView,您应该能够使用GridViewColumn s中的CellTemplateCellTemplateSelector

如果你真的想访问特定的单元格,我认为没有干净的方法,你最好使用DataGrid(来自。net 4或。net 3.5的WPF工具包)。有了它,你可以这样做:

((TextBlock)datagrid.Columns[1].GetCellContent(m_specificItem)).Background = Brushes.Red