WPF-触发器问题
我有两个带有触发器的 ListView,在选定时将背景颜色更改为深灰色,将前景色更改为白色。 问题是,当我在第一个列表视图中选择一个项目,然后在第二个列表视图中选择一个项目时,第一个列表视图前景中的项目不会再次变黑,而是保持白色。
xaml:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="190*" />
<RowDefinition Height="121*" />
</Grid.RowDefinitions>
<Grid.Resources>
<ResourceDictionary>
<Style x:Key="@ListViewItemStyle" TargetType="{x:Type ListViewItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType='{x:Type ListViewItem}'>
<Grid SnapsToDevicePixels="True" Margin="0">
<Border x:Name="Bd" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" />
<GridViewRowPresenter x:Name="Content" TextBlock.Foreground="{TemplateBinding Foreground}"
Content="{TemplateBinding Content}" Columns="{TemplateBinding GridView.ColumnCollection}" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter Property="TextElement.Foreground" Value="White" TargetName="Content" />
<Setter Property="Background" Value="DarkGray" TargetName="Bd"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true" />
<Condition Property="Selector.IsSelectionActive" Value="false" />
</MultiTrigger.Conditions>
<Setter Property="Background" TargetName="Bd"
Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
</MultiTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<DataTemplate x:Key="@TextCellTemplate">
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
<DataTemplate x:Key="@TrubleCellTemplate">
<Rectangle Width="20" Height="20" Fill="Black"></Rectangle>
</DataTemplate>
</ResourceDictionary>
</Grid.Resources>
<ListView ItemsSource="{Binding Persons}" Style="{DynamicResource @ListView}" ItemContainerStyle="{DynamicResource @ListViewItemStyle}">
<ListView.View>
<GridView>
<GridViewColumn Width="40" CellTemplate="{DynamicResource @TextCellTemplate}" />
<GridViewColumn Width="131" CellTemplate="{DynamicResource @TrubleCellTemplate}" />
</GridView>
</ListView.View>
</ListView>
<ListView ItemsSource="{Binding Persons}" Style="{DynamicResource @ListView}" ItemContainerStyle="{DynamicResource @ListViewItemStyle}" Grid.Row="1">
<ListView.View>
<GridView>
<GridViewColumn Width="40" CellTemplate="{DynamicResource @TextCellTemplate}" />
<GridViewColumn Width="131" CellTemplate="{DynamicResource @TrubleCellTemplate}" />
</GridView>
</ListView.View>
</ListView>
</Grid>
I have two ListViews with trigger that on selected change the background color to dark gray and the foreground color to white.
The problem is that when I select an item in the first listview and then an item in the second listview the item in the first listview foreground doesn't get black again and it stay white.
the xaml:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="190*" />
<RowDefinition Height="121*" />
</Grid.RowDefinitions>
<Grid.Resources>
<ResourceDictionary>
<Style x:Key="@ListViewItemStyle" TargetType="{x:Type ListViewItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType='{x:Type ListViewItem}'>
<Grid SnapsToDevicePixels="True" Margin="0">
<Border x:Name="Bd" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" />
<GridViewRowPresenter x:Name="Content" TextBlock.Foreground="{TemplateBinding Foreground}"
Content="{TemplateBinding Content}" Columns="{TemplateBinding GridView.ColumnCollection}" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter Property="TextElement.Foreground" Value="White" TargetName="Content" />
<Setter Property="Background" Value="DarkGray" TargetName="Bd"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true" />
<Condition Property="Selector.IsSelectionActive" Value="false" />
</MultiTrigger.Conditions>
<Setter Property="Background" TargetName="Bd"
Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
</MultiTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<DataTemplate x:Key="@TextCellTemplate">
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
<DataTemplate x:Key="@TrubleCellTemplate">
<Rectangle Width="20" Height="20" Fill="Black"></Rectangle>
</DataTemplate>
</ResourceDictionary>
</Grid.Resources>
<ListView ItemsSource="{Binding Persons}" Style="{DynamicResource @ListView}" ItemContainerStyle="{DynamicResource @ListViewItemStyle}">
<ListView.View>
<GridView>
<GridViewColumn Width="40" CellTemplate="{DynamicResource @TextCellTemplate}" />
<GridViewColumn Width="131" CellTemplate="{DynamicResource @TrubleCellTemplate}" />
</GridView>
</ListView.View>
</ListView>
<ListView ItemsSource="{Binding Persons}" Style="{DynamicResource @ListView}" ItemContainerStyle="{DynamicResource @ListViewItemStyle}" Grid.Row="1">
<ListView.View>
<GridView>
<GridViewColumn Width="40" CellTemplate="{DynamicResource @TextCellTemplate}" />
<GridViewColumn Width="131" CellTemplate="{DynamicResource @TrubleCellTemplate}" />
</GridView>
</ListView.View>
</ListView>
</Grid>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的模板中的两个触发器之间存在干扰。当您第一次选择 ListView #1 中的值时,第一个 IsSelected 触发器将被激活。这会将 TemplateBinding 中“Content”上的 TextBlock.Foreground 值覆盖为固定值 White。
当 ListView #1 失去焦点到 ListView #2 时,第二个触发器(IsSelected 和 IsSelectionActive 的 MultiTrigger)也会被激活。这会导致“Bd”的背景被设置为不同的值(与其他触发器相同),并且因为它是稍后在触发器集合中声明的,所以会覆盖仍处于活动状态的上一个触发器。
Foreground setter 也应该发生同样的情况,但是 MultiTrigger 中的设置器是在父控件而不是“Content”上设置 Foreground。由于“Content”不再使用 TemplateBinding 来拉入父控件的 Foreground 值,因此第一个触发器的 White 值在“Content”元素上保持活动状态。
You're getting interference between two of the Triggers in your template. The first IsSelected Trigger becomes active when you first select the value in ListView #1. This overrides the TextBlock.Foreground value on "Content" from the TemplateBinding to a fixed value of White.
When ListView #1 loses focus to ListView #2 the second trigger (MultiTrigger for IsSelected and IsSelectionActive) is also activated. This causes the Background of "Bd" to be set to a different value (same as the other Trigger) and, because it's declared later in the Triggers collection, overrides the previous Trigger which is still active.
The same should happen for the Foreground setter, but the one in the MultiTrigger is setting the Foreground on the parent control instead of on "Content". Because "Content" is no longer using TemplateBinding to pull in the parent control's Foreground value the first Trigger's White value remains active on the "Content" element.