列表框鼠标移到背景色上 [英] ListBox mouse over background color

查看:73
本文介绍了列表框鼠标移到背景色上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到的问题是MouseOver触发器为选定行上的背景着色失败.
对于任何未选中的行,鼠标悬停时背景都会变为蓝色.
但是所选行没有蓝色背景.
单击一行,然后背景蓝色消失.

The problem I have is the MouseOver trigger to color the background fails on the selected row.
For any non-selected row the background turns blue on mouse over.
But no blue background for the selected row.
Click on a row and then the background blue goes away.

我还尝试了ListBox.ItemContainerStyle

I also tried the style in the ListBox.ItemContainerStyle

<Window x:Class="ListBoxLastIntoView.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="0"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <ListBox Grid.Row="1" Grid.ColumnSpan="2" x:Name="lvMVitems" 
            ItemsSource="{Binding Mode=OneWay}" 
            ScrollViewer.CanContentScroll="False" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Auto" MaxHeight="300">
            <ListBox.Resources>
                <Style TargetType="ListBoxItem">
                    <Style.Resources>
                        <!-- Background of selected item when focussed -->
                        <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent"/>
                        <!-- Background of selected item when not focussed -->
                        <SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="Transparent" />
                    </Style.Resources>
                    <Style.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Background" Value="LightSteelBlue" />
                        </Trigger>
                    </Style.Triggers>
                </Style>                 
            </ListBox.Resources>
            <!--<ListBox.ItemContainerStyle>               
            </ListBox.ItemContainerStyle>-->
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{TemplateBinding Content}" Background="Orange" Margin="20,2,2,2">
                    </TextBlock>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Window>


namespace ListBoxLastIntoView
{
    public partial class MainWindow : Window
    {
        private string lorum = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
        private List<string> lorums = new List<string>();
        public MainWindow()
        {
            for (int i = 1; i < 100; i++) lorums.Add(i.ToString() + " " + lorum);           
            InitializeComponent();
            //lb.ItemsSource = lorums;
            lvMVitems.ItemsSource = lorums;
        }
    }
}

推荐答案

如果查看ListBoxItem的默认模板,则会看到 IsMouseOver触发器在IsSelected触发器之前应用,并且由于dataTriggers从上到下进行评估.因此,最后一个触发器总是会赢,并将ListBoxItem的背景设置为Transparent (在您的情况下).

If you look at default template of ListBoxItem, you will see IsMouseOver trigger is applied before IsSelected trigger and since dataTriggers are evaluated from top to bottom. So, last trigger always won and set background of ListBoxItem as Transparent (in your case).

如果您想覆盖该行为,则必须覆盖默认模板,并在那里设置值并更改触发器的顺序.下面是示例操作方法,您可以根据需要更改背景颜色和边框画笔:

In case you want to override that behaviour, you have to override default template and set your values over there and change ordering of triggers. Below is the sample how to do it, you can change background colors and border brushes as per your needs:

<Style TargetType="ListBoxItem">
  <Setter Property="Template">
     <Setter.Value>
       <ControlTemplate TargetType="ListBoxItem">
          <Border BorderThickness="{TemplateBinding Border.BorderThickness}"
                  Padding="{TemplateBinding Control.Padding}"
                  BorderBrush="{TemplateBinding Border.BorderBrush}"
                  Background="{TemplateBinding Panel.Background}"
                  Name="Bd"
                  SnapsToDevicePixels="True">
             <ContentPresenter Content="{TemplateBinding ContentControl.Content}"
                               ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
                               ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}"
                               HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
                               VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}"
                               SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
          </Border>
          <ControlTemplate.Triggers>
             <MultiTrigger>
                <MultiTrigger.Conditions>
                  <Condition Property="Selector.IsSelectionActive" Value="False"/>
                  <Condition Property="Selector.IsSelected" Value="True"/>
                </MultiTrigger.Conditions>
                <Setter Property="Panel.Background" TargetName="Bd" 
                        Value="Transparent"/>
                <Setter Property="Border.BorderBrush" TargetName="Bd">
                   <Setter.Value>
                     <SolidColorBrush>#FFDADADA</SolidColorBrush>
                   </Setter.Value>
                </Setter>
             </MultiTrigger>
             <MultiTrigger>
               <MultiTrigger.Conditions>
                 <Condition Property="Selector.IsSelectionActive" Value="True"/>
                 <Condition Property="Selector.IsSelected" Value="True"/>
               </MultiTrigger.Conditions>
               <Setter Property="Panel.Background" TargetName="Bd" Value="Transparent"/>
               <Setter Property="Border.BorderBrush" TargetName="Bd">
                 <Setter.Value>
                   <SolidColorBrush>#FF26A0DA</SolidColorBrush>
                 </Setter.Value>
               </Setter>
             </MultiTrigger>
             <Trigger Property="UIElement.IsMouseOver" Value="True">
               <Setter Property="Panel.Background" TargetName="Bd" 
                       Value="LightSteelBlue"/>
               <Setter Property="Border.BorderBrush" TargetName="Bd">
                 <Setter.Value>
                   <SolidColorBrush>#A826A0DA</SolidColorBrush>
                 </Setter.Value>
               </Setter>
             </Trigger>
             <Trigger Property="UIElement.IsEnabled" Value="False">
               <Setter Property="TextElement.Foreground" TargetName="Bd">
                 <Setter.Value>
                   <DynamicResource ResourceKey="{x:Static SystemColors.GrayTextBrushKey}" />
                 </Setter.Value>
               </Setter>
             </Trigger>
          </ControlTemplate.Triggers>
       </ControlTemplate>
     </Setter.Value>
   </Setter>
</Style>


更新

也许我应该在上面对我的主张做些解释.

May be I should explain a bit more about my assertions above.

首先,我可以使用Windows 8,并且Windows 7和Windows 8的默认模板大不相同.对于Windows 8,主题样式是从PresentationFramework.Aero2.dll中选取的,因此默认模板可能与下面的主题样式有所不同. PresentationFramework.Aero.dll(用于Windows 7和更早版本).

First of all, I had Windows 8 at my disposal and default templates are quite different for Windows 7 and Windows 8. For Windows 8, theme styles are picked from PresentationFramework.Aero2.dll, hence defualt templates might differ from theme style found under PresentationFramework.Aero.dll (used for Windows 7 and earlier versions).

我已经发布了我从Aero2.dll获得的默认模板.正如您在默认模板中看到的那样,它不使用HighlightBrushKey,因此您最初在覆盖HighlightBrushKey的位置发布的问题一开始就不起作用. (这就是为什么我不喜欢覆盖系统画笔,因为它可能不适用于使用其他主题样式的模板).

I have posted default template I got from Aero2.dll. As you can see in default template, it doesn't use HighlightBrushKey so the question you posted where you are overriding HighlightBrushKey doesn't work at first place. (That's why I don't like overriding System brushes since it might not work for templates using another Theme style).

根据开发人员的回答

无论如何,样式触发器优先于模板触发器,因此它 模板触发器是位于第一个还是最后一个位置都没关系 列表.

Style triggers take precedence over template triggers anyways so it wouldn't matter if the template trigger is at first or last place in list.

我同意样式触发器优先于模板触发器.但是,我在回答中提到的情况是您没有使用任何样式触发器,而只是在模板中提供值的情况.默认情况下,模板MouseOverTrigger位于顶部,而SelectedItem触发位于其下方.因此,在那种情况下顺序很重要.您可以通过向上移动触发器并删除所有样式触发器来验证自己.

I agree that Style triggers take precedence over template triggers. But, what i mentioned in my answer was the case when you haven't used any Style triggers and simply provide values in template. In default template MouseOverTrigger is at top and SelectedItem trigger below that. So, in that case order does matter. You can verify that your self by moving up the trigger and removing all Style triggers.

关于

我不确定Rohit发布给您的样式是否是的完整副本 ListBoxItem样式.似乎缺少风格设定者.他只是 我猜给你贴了模板.

I am not sure if the style Rohit posted to you is a complete copy of the ListBoxItem style. There seem to be style setters missing. He just posted you the template I guess.

我已经发布了在Aero2.dll下找到的ListBoxItem的完整模板,显然,该模板可能会根据主题样式而有所不同.

I have posted the complete template of ListBoxItem found under Aero2.dll which obviously might differ based on theme style.

我使用XamlWriter.Save(listBoxItem.Template, xmlwrite);

这篇关于列表框鼠标移到背景色上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆