问题描述
我遇到的问题是鼠标悬停触发器在所选行上为背景着色失败.
对于任何未选择的行,鼠标悬停时背景变为蓝色.
但所选行没有蓝色背景.
单击一行,然后背景蓝色消失.
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
触发器 之前应用.由于 DataTrigger
是从上到下评估的,所以 最后一个触发器总是会获胜,并将 ListBoxItem
的 Background
设置为 透明
(在你的情况下).
If you look at the default template of ListBoxItem
, you will see the IsMouseOver
trigger is applied before the IsSelected
trigger. Since DataTrigger
s are evaluated from top to bottom, the last trigger will always win and set the Background
of ListBoxItem
as Transparent
(in your case).
如果您想覆盖该行为,则必须覆盖默认模板并更改触发器的顺序.下面是一个示例,展示了如何做到这一点,您可以根据需要更改背景颜色和边框画笔:
If you want to override that behavior, you'll have to override default template and change ordering of triggers. Below is a sample showing 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>
<小时>
更新
也许我应该多解释一下我上面的断言.
Maybe 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 the default templates are quite different between Windows 7 and Windows 8. For Windows 8, theme styles are picked from PresentationFramework.Aero2.dll
, hence the default templates might differ from theme style found under PresentationFramework.Aero.dll
(used for Windows 7 and earlier versions).
我在从 Aero2.dll
获得的默认模板上方发布.如您所见,它不使用 HighlightBrushKey
因此覆盖 HighlightBrushKey
的建议在这种情况下不起作用.(这就是我不喜欢覆盖系统画笔的原因,因为它可能不适用于使用其他主题样式的模板.
I posted above the default template I got from Aero2.dll
. As you can see, it doesn't use HighlightBrushKey
so the suggestion of overriding HighlightBrushKey
doesn't work in this case. (That's why I don't like overriding system brushes, since it might not work for templates using another theme style).
根据 Dev 的回答
无论如何,样式触发器优先于模板触发器,所以它模板触发器是在第一个还是最后一个位置都没有关系列表.
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.
我同意 Style
触发器优先于模板触发器.但是,我在回答中提到的情况是您没有使用任何 Style
触发器并且只是在模板中提供值.在默认模板中,MouseOver
触发器位于顶部,而 SelectedItem
触发器位于其下方,因此在这种情况下顺序很重要.您可以通过向上移动触发器并删除所有 Style
触发器来验证自己.
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 the template. In the default template the MouseOver
trigger is at top and the SelectedItem
trigger below that, so in that case order does matter. You can verify that yourself 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);
这篇关于ListBox 鼠标悬停在背景颜色上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!