在列表视图中设置单个单元格的样式

时间:2011-05-01 12:27:57

标签: c# .net wpf listview styling

在互联网上,我发现了许多在列表视图中设置完整列或完整行样式的示例。

我需要能够在列表视图中动态设置单个单元格的样式。如何连续访问各个项目的属性?

2 个答案:

答案 0 :(得分:2)

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

您还可以使用转换器(内置或自定义)轻松获得一些效果。例如,我使用内置布尔到可见性转换器来隐藏/取消隐藏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。我从来没有使用过它,但如果你有很多数据模板需要处理,它似乎是理想的。

答案 1 :(得分:0)

一般来说,你不应该需要这个。假设您使用的是GridView,则应该可以使用CellTemplate的{​​{1}}或CellTemplateSelector

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

DataGrid