如何设置WPF ListView选定项的颜色?

16

我正在尝试在运行Windows 7的WPF应用程序中重新创建Windows 8的邮件UI。 我想要实现以下目标:

目标UI

特别是,我不知道如何更改所选项目的背景颜色,例如第一列中的收件箱项目和第二列中来自Twitter的邮件。 我尝试了其他类似的Stackoverflow问题提供的几个解决方案,但都不适用于我。例如:

WPF ListBox中当焦点移出时所选项失去样式

WPF ListView非活动选择颜色

这是我listview的代码:

<ListView Grid.Row="0" SelectedItem="{Binding Path=SelectedArea}" ItemsSource="{Binding Path=Areas}" Background="#DCE3E5" >

                    <ListView.Resources>

                        <!-- Template that is used upon selection of an Area -->
                        <ControlTemplate x:Key="SelectedTemplate" TargetType="ListViewItem">
                            <Border Background="#388095" Cursor="Hand" >
                                <TextBlock Text="{Binding Name}" Margin="5" />
                            </Border>                                
                        </ControlTemplate>

                        <Style TargetType="ListViewItem">
                            <Setter Property="Template">
                                <Setter.Value>                                        
                                    <!-- Base Template that is replaced upon selection -->
                                    <ControlTemplate TargetType="ListViewItem">
                                        <Border Background="#DCE3E5" Cursor="Hand"  >
                                            <TextBlock Text="{Binding Name}" Margin="5" />
                                        </Border>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                            <Style.Triggers>
                                <MultiTrigger>
                                    <MultiTrigger.Conditions>
                                        <Condition Property="IsSelected" Value="true" />
                                    </MultiTrigger.Conditions>
                                    <Setter Property="Template" Value="{StaticResource SelectedTemplate}" />
                                </MultiTrigger>
                            </Style.Triggers>
                        </Style>

                    </ListView.Resources>                        

                </ListView>

我怎样才能改变选定项的背景颜色?并且在焦点变化时如何保留颜色更改。

2个回答

22

我最近做过类似的事情:

<ListView.Resources>                
    <ControlTemplate x:Key="SelectedTemplate" TargetType="ListViewItem">
        <Border CornerRadius="5" BorderThickness="1" BorderBrush="DarkGray" Background="#FF92C6F9" Padding="2" HorizontalAlignment="Left" Margin="5" Tag="{Binding Value}" Cursor="Hand" MouseUp="Border_MouseUp_1">                        
            <TextBlock Text="{Binding Name}" Margin="5" />
        </Border>
    </ControlTemplate>
    <Style TargetType="ListViewItem">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListViewItem">
                    <Border CornerRadius="5" BorderThickness="1" BorderBrush="DarkGray" Background="WhiteSmoke" Padding="2" HorizontalAlignment="Left" Margin="5" Tag="{Binding Value}" Cursor="Hand" MouseUp="Border_MouseUp_1" >                                    
                        <TextBlock Text="{Binding Name}" Margin="5" />
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <MultiTrigger>
                <MultiTrigger.Conditions>
                    <Condition Property="IsSelected" Value="true" />
                    <Condition Property="Selector.IsSelectionActive" Value="true" />
                </MultiTrigger.Conditions>                            
                <Setter Property="Template" Value="{StaticResource SelectedTemplate}" />                            
            </MultiTrigger>
        </Style.Triggers>
    </Style>
</ListView.Resources>

我相信移除:

<Condition Property="Selector.IsSelectionActive" Value="true" />

将允许您在失去焦点后保留背景颜色。

编辑:

回答下面的问题:

您可以将TextBlock的tag属性绑定到命令参数,然后在TextBlock的MouseUp事件上执行该命令:

<TextBlock x:Name="MyTextBlock" Text="Click Me!" Tag="{Binding MyCommandParameter}" MouseUp="MyTextBlock_MouseUp" />

在后台代码中:

    private void MyTextBlock_MouseUp(object sender, MouseButtonEventArgs e)
    {
        TextBlock tb = sender as TextBlock;

        if (tb != null && tb.Tag != null)
        {
            ViewModel.MyCommand.Execute(tb.Tag);
        }            
    }

感谢@TrueEddie。我的机器出了点问题,无法测试您的解决方案。我会尽快修好我的机器并回复您。 - Yasir
这样可以正确显示选择。但是现在我们使用的是TextBlock而不是我之前使用的超链接,因此我无法提供所需调用的Command。我该如何提供命令和相关参数?当我用超链接替换您的Border元素时,它允许我在超链接外单击时更改颜色,但不允许我调用命令。当我单击超链接时,它允许我调用命令,但颜色没有改变。 - Yasir
编辑对我没有起作用,但我能够将ListView SelectedItem绑定到我在MVVM模型中创建的Dependency Property,并在此属性更改时加载下一个listview。这消除了超链接的需要,我已经从您的代码中获得了背景颜色。所以,现在我有了完整的解决方案。非常感谢您的帮助。我将在几分钟内发布我的问题中的最终ListView。 - Yasir

10

补充"TrueEddie"的观点。

另一个选项是ListView中的"ItemContainerStyle"。

  <ListView Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" 


                  BorderThickness="0" 
                     ItemContainerStyle="{StaticResource ListViewSmartNotes}"
                  SelectedItem="{Binding SelectedSmartNotes, Mode=TwoWay}"
                  ItemsSource="{Binding LstSmartNotes, Mode=TwoWay}" 
                  ItemTemplate="{DynamicResource ListViewItemOptionStyle}">


        </ListView>

在Style.xml中定义的ListViewItemOptionStyle

<Style x:Key="ListViewItemOptionStyle" TargetType="ListViewItem">
        <Setter Property="Template">
            <Setter.Value>
                <!-- Trun off default selection-->
                <ControlTemplate TargetType="{x:Type ListViewItem}">
                    <Border x:Name="Bd" BorderBrush="Gray" BorderThickness="0,1,0,1" 
                            Background="{TemplateBinding Background}" 
                            Padding="{TemplateBinding Padding}" 
                            SnapsToDevicePixels="true">
                        <ContentPresenter 
                            HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                            SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" 
                            VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Foreground"
                                    Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
        </Setter.Value>
        </Setter>
    <Style.Triggers>
        <MultiTrigger>
            <MultiTrigger.Conditions>
                <Condition Property="IsSelected" Value="True" />
            </MultiTrigger.Conditions>
            <MultiTrigger.Setters>
                <Setter Property="Background" Value="Green" />
                <Setter Property="BorderBrush" Value="Green" />
                <Setter Property="Foreground" Value="White"/>
            </MultiTrigger.Setters>
        </MultiTrigger>
    </Style.Triggers>
</Style>

了解更多细节请访问https://sites.google.com/site/greateindiaclub/mobil-apps/windows8/wpfimportantbindings


6
我相信你的 ItemContainerStyleItemTemplate 绑定是颠倒的,应该更改为 ItemContainerStyle="{StaticResource ListViewItemOptionStyle}",否则会出现转换异常。另外,如果涉及多列,请使用 <GridViewRowPresenter Content="{TemplateBinding Content}" />,而不是使用 <ContentPresenter /> - famousKaneis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接