选择但失去焦点时更改 WPF treeViewItem 背景颜色

Posted

技术标签:

【中文标题】选择但失去焦点时更改 WPF treeViewItem 背景颜色【英文标题】:Change WPF treeViewItem Background color when selected but lost focus 【发布时间】:2014-03-03 14:20:41 【问题描述】:

当 TreeViewItem 被选中但失去焦点时,我正在尝试更改它的背景颜色。 我看到了一些类似的问题,例如: WPF TreeViewItem Background ,但我无法使用它...

这是我的树视图 Xaml 代码:

>     <UserControl x:Class="Ednfi.Setup.Presentation.Views.TreeViewViews.StationTree"
> xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
> xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
> xmlns:behaviour="clr-namespace:Ednfi.Setup.Presentation.Extensions;assembly=Ednfi.Setup.Presentation"
> xmlns:nodes="clr-namespace:Ednfi.Setup.Presentation.ViewModels.TreeViewViewModels.Nodes"
> mc:Ignorable="d"
> xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
> xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
> d:DesignHeight="226" d:DesignWidth="227"
> xmlns:ml="clr-namespace:Ednfi.Setup.Presentation.ml_resources">
>         <TreeView Margin="10 0 10 20" ItemsSource="Binding Path=Root.Children" VirtualizingStackPanel.IsVirtualizing="True"
> VirtualizingStackPanel.VirtualizationMode="Recycling">
>     
>     
>             <TreeView.ItemContainerStyle>
>                 <Style TargetType="x:Type TreeViewItem">
>                     <Setter Property="IsSelected" Value="Binding Path=IsSelected, Mode=TwoWay"/>
>                     <Setter Property="IsExpanded" Value="Binding Path=IsExpanded, Mode=TwoWay" />
>                 </Style>
>             </TreeView.ItemContainerStyle>
>             <TreeView.Resources>
>                 <Style TargetType="x:Type TreeViewItem">
>                     <Setter Property="Background" Value="Transparent" />
>                     <Setter Property="HorizontalContentAlignment" Value="Binding Path=HorizontalContentAlignment,
> RelativeSource=RelativeSource AncestorType=x:Type ItemsControl"
> />
>                     <Setter Property="VerticalContentAlignment" Value="Binding Path=VerticalContentAlignment,
> RelativeSource=RelativeSource AncestorType=x:Type ItemsControl"
> />
>                     <Setter Property="Padding" Value="1,0,0,0" />
>                     <Setter Property="IsExpanded" Value="Binding IsExpanded, Mode=TwoWay" />
>                     <Setter Property="IsSelected" Value="Binding IsSelected, Mode=TwoWay" />
>                     <Setter Property="behaviour:TreeViewItemBehavior.IsBroughtIntoViewWhenSelected"
> Value="True" />
>                     <Setter Property="Template">
>                         <Setter.Value>
>                             <ControlTemplate TargetType="x:Type TreeViewItem">
>                                 <Grid>
>                                     <Grid.ColumnDefinitions>
>                                         <ColumnDefinition MinWidth="19" Width="Auto" />
>                                         <ColumnDefinition Width="Auto" />
>                                         <ColumnDefinition Width="*" />
>                                     </Grid.ColumnDefinitions>
>                                     <Grid.RowDefinitions>
>                                         <RowDefinition Height="Auto" />
>                                         <RowDefinition />
>                                     </Grid.RowDefinitions>
>                                     <ToggleButton x:Name="Expander" IsChecked="Binding Path=IsExpanded, RelativeSource=RelativeSource
> TemplatedParent" ClickMode="Press" />
>                                     <Border Grid.Column="1" x:Name="Selection_Border" Background="TemplateBinding Background"
> BorderBrush="TemplateBinding BorderBrush"
> BorderThickness="TemplateBinding BorderThickness"
> Padding="TemplateBinding Padding">
>                                         <ContentPresenter HorizontalAlignment="TemplateBinding HorizontalContentAlignment"
> x:Name="PART_Header" ContentSource="Header" />
>                                     </Border>
>                                     <ItemsPresenter Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="1" x:Name="ItemsHost" />
>                                 </Grid>
>                                 <ControlTemplate.Triggers>
>                                     <Trigger Property="IsExpanded" Value="false">
>                                         <Setter Property="Visibility" Value="Collapsed" TargetName="ItemsHost" />
>                                     </Trigger>
>                                     <Trigger Property="HasItems" Value="false">
>                                         <Setter Property="Visibility" Value="Hidden" TargetName="Expander" />
>                                     </Trigger>
>                                     <Trigger Property="IsSelected" Value="true">
>                                         <Setter Property="Background" Value="DynamicResource x:Static SystemColors.HighlightBrushKey"
> TargetName="Selection_Border" />
>                                         <Setter Property="Foreground" Value="DynamicResource x:Static
> SystemColors.HighlightTextBrushKey" />
>                                     </Trigger>
>                                     <MultiTrigger>
>                                         <MultiTrigger.Conditions>
>                                             <Condition Property="IsSelected" Value="true" />
>                                             <Condition Property="IsSelectionActive" Value="false" />
>                                         </MultiTrigger.Conditions>                                    
>                                         <Setter Property="Background" Value="DynamicResource x:Static SystemColors.HighlightBrushKey"
> TargetName="Selection_Border" />                                    
>                                         <Setter Property="Foreground" Value="DynamicResource x:Static
> SystemColors.HighlightTextBrushKey" />
>                                     </MultiTrigger>
>                                     <Trigger Property="IsEnabled" Value="false">
>                                         <Setter Property="Foreground" Value="DynamicResource x:Static SystemColors.GrayTextBrushKey" />
>                                     </Trigger>
>                                 </ControlTemplate.Triggers>
>                             </ControlTemplate>
>                         </Setter.Value>
>                     </Setter>
>                 </Style>
>                 <!-- Style for the ToggleButton control used to expand/collapse a TreeViewItem control -->
>                 <Style TargetType="x:Type ToggleButton">
>                     <Setter Property="Focusable" Value="False" />
>                     <Setter Property="Width" Value="19" />
>                     <Setter Property="Height" Value="13" />
>                     <Setter Property="Template">
>                         <Setter.Value>
>                             <ControlTemplate TargetType="x:Type ToggleButton">
>                                 <Border Width="19" Height="13" Background="#00FFFFFF" x:Name="Border">
>                                     <Border Width="9" Height="9" x:Name="Border1" SnapsToDevicePixels="True" BorderBrush="#FF9495A2"
> BorderThickness="1,1,1,1" CornerRadius="1,1,1,1">
>                                         <Border.Background>
>                                             <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
>                                                 <GradientStop Color="#FFFFFFFF" Offset="0.4" />
>                                                 <GradientStop Color="#FFC6CEDA" Offset="1" />
>                                             </LinearGradientBrush>
>                                         </Border.Background>
>                                         <Path Fill="#FF000000" Margin="1,1,1,1" x:Name="ExpandPath" Data="M0,2L0,3 2,3 2,5 3,5 3,3
> 5,3 5,2 3,2 3,0 2,0 2,2z" />
>                                     </Border>
>                                 </Border>
>                                 <ControlTemplate.Triggers>
>                                     <Trigger Property="IsChecked" Value="True">
>                                         <Setter Property="Data" Value="M0,2L0,3 5,3 5,2z" TargetName="ExpandPath" />
>                                     </Trigger>
>                                 </ControlTemplate.Triggers>
>                             </ControlTemplate>
>                         </Setter.Value>
>                     </Setter>
>                 </Style>
>                 <DataTemplate DataType="x:Type nodes:MonitorNode">
>                     <StackPanel Orientation="Horizontal" Margin="0 2 0 0">
>                         <Image Source="Binding ImageSource" Width="16" Height="16" Margin="0 0 3 0" />
>                         <TextBlock Text="x:Static ml:MultiLang._157" x:Name="ML_0048" />
>                         <TextBlock Text="Binding ID" />
>                         <TextBlock Text="x:Static ml:MultiLang._158" x:Name="ML_0050" />
>                         <TextBlock Text="Binding Name" />
>                     </StackPanel>
>                 </DataTemplate>
>                 <HierarchicalDataTemplate DataType="x:Type nodes:StationNode" ItemsSource="Binding Children">
>                     <StackPanel Orientation="Horizontal" Margin="0 2 0 0">
>                         <StackPanel.ContextMenu>
>                             <ContextMenu HasDropShadow="True">
>                                 <MenuItem Header="x:Static ml:MultiLang._160" Command="Binding CopyMonitorsCommand"
> x:Name="ML_0055" />
>                                 <MenuItem Header="x:Static ml:MultiLang._159" Command="Binding PasteMonitorsCommand"
> x:Name="ML_0056" />
>                                 <MenuItem Header="x:Static ml:MultiLang._162" Command="Binding CopyStationsCommand"
> x:Name="ML_0057" />
>                                 <MenuItem Header="x:Static ml:MultiLang._161" Command="Binding PasteStationsCommand"
> x:Name="ML_0058" />
>                             </ContextMenu>
>                         </StackPanel.ContextMenu>
>                         <Image Source="Binding ImageSource" Width="16" Height="16" Margin="0 0 3 0" />
>                         <TextBlock Text="x:Static ml:MultiLang._157" x:Name="ML_0060" />
>                         <TextBlock Text="Binding ID" />
>                         <TextBlock Text="x:Static ml:MultiLang._158" x:Name="ML_0062" />
>                         <TextBlock Text="Binding Name" />
>                     </StackPanel>
>                 </HierarchicalDataTemplate>
>                 <HierarchicalDataTemplate DataType="x:Type nodes:FilteringNode" ItemsSource="Binding Children">
>                     <StackPanel Orientation="Horizontal" Margin="0 2 0 0">
>                         <Image Source="Binding ImageSource" Width="16" Height="16" Margin="0 0 3 0" />
>                         <TextBlock Text="Binding Name" />
>                     </StackPanel>
>                 </HierarchicalDataTemplate>
>             </TreeView.Resources>
>         </TreeView>
>     </UserControl>

选中时当前背景颜色为蓝色。

但是当仍然被选中,但失去焦点时,背景颜色是灰色的。

我只想让它保持蓝色! 感谢您的帮助。

【问题讨论】:

【参考方案1】:

关于另一个post,ControlBrushKey 对我不起作用。但是,InactiveSelectionHighlightBrushKey 做到了。还设置InactiveSelectionHighlightTextBrushKey 绕过了不断变化的文本颜色。

我的完整解决方案:

<TreeView.Resources>
    <!-- Style the inactive selection the same as active -->
    <SolidColorBrush x:Key="x:Static SystemColors.InactiveSelectionHighlightBrushKey"
                     Color="DynamicResource x:Static SystemColors.HighlightColorKey" />
    <SolidColorBrush x:Key="x:Static SystemColors.InactiveSelectionHighlightTextBrushKey"
                     Color="DynamicResource x:Static SystemColors.HighlightTextColorKey"/>
</TreeView.Resources>

【讨论】:

【参考方案2】:

TreeViewItem 的默认模板中,有 MultiDataTrigger 将颜色设置为 ControlBrushKey,当项目不在焦点时,您可以在 TreeView 资源中覆盖,如下所示:

<TreeView.ItemContainerStyle>
   <Style TargetType="x:Type TreeViewItem">
      <Style.Resources>
         <SolidColorBrush x:Key="x:Static SystemColors.ControlBrushKey"
                       Color="#FF3399FF"/>
      </Style.Resources>
      ...
   </Style>
<TreeView.ItemContainerStyle>

那么就不需要重写TreeViewItem的ControlTemplate了。

但是,它也将 treeViewItem 的文本设置为 ControlTextBrushKey,默认情况下为黑色。所以,只有ControlBrushKey 被覆盖,你会得到它这样的工作:

没有焦点

专注

如您所见,画笔已被正确覆盖,但如果您覆盖 ControlTextBrushKey 并将其设置为白色,则 treeView 项目将不可见,因为 controlTextBrush 将设置为白色。


但是,如果您希望 TreeViewItem 具有与焦点完全相同的外观,则必须覆盖控件模板并从默认模板中删除该 MultiDataTrigger。

默认模板如下所示:

    <TreeView>
        <TreeView.ItemContainerStyle>
            <Style TargetType="TreeViewItem">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="TreeViewItem">
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="Auto" MinWidth="19" />
                                    <ColumnDefinition Width="Auto" />
                                    <ColumnDefinition Width="*" />
                                </Grid.ColumnDefinitions>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="Auto" />
                                    <RowDefinition/>
                                </Grid.RowDefinitions>
                                <ToggleButton IsChecked="False"
                                              ClickMode="Press"
                                              Name="Expander">
                                    <ToggleButton.Style>
                                        <Style TargetType="ToggleButton">
                                            <Style.Resources>
                                                <ResourceDictionary />
                                            </Style.Resources>
                                            <Setter Property="UIElement.Focusable" Value="False"/>
                                            <Setter Property="FrameworkElement.Width" Value="16"/>
                                            <Setter Property="FrameworkElement.Height" Value="16"/>
                                            <Setter Property="Control.Template">
                                                <Setter.Value>
                                                    <ControlTemplate TargetType="ToggleButton">
                                                        <Border Padding="5,5,5,5"
                                                                Background="#00FFFFFF"
                                                                Width="16"
                                                                Height="16">
                                                            <Path Fill="#FFFFFFFF"
                                                                  Stroke="#FF818181"
                                                                  Name="ExpandPath">
                                                                <Path.Data>
                                                                    <PathGeometry Figures="M0,0L0,6L6,0z" />
                                                                </Path.Data>
                                                                <Path.RenderTransform>
                                                                    <RotateTransform Angle="135" CenterX="3" CenterY="3" />
                                                                </Path.RenderTransform>
                                                            </Path>
                                                        </Border>
                                                        <ControlTemplate.Triggers>
                                                            <Trigger Property="ToggleButton.IsChecked" Value="True">
                                                                <Setter Property="UIElement.RenderTransform" TargetName="ExpandPath">
                                                                    <Setter.Value>
                                                                        <RotateTransform Angle="180" CenterX="3" CenterY="3" />
                                                                    </Setter.Value>
                                                                </Setter>
                                                                <Setter Property="Shape.Fill" TargetName="ExpandPath">
                                                                    <Setter.Value>
                                                                        <SolidColorBrush>#FF595959</SolidColorBrush>
                                                                    </Setter.Value>
                                                                </Setter>
                                                                <Setter Property="Shape.Stroke" TargetName="ExpandPath">
                                                                    <Setter.Value>
                                                                        <SolidColorBrush>#FF262626</SolidColorBrush>
                                                                    </Setter.Value>
                                                                </Setter>
                                                            </Trigger>
                                                            <Trigger Property="UIElement.IsMouseOver" Value="True">
                                                                <Setter Property="Shape.Stroke" TargetName="ExpandPath">
                                                                    <Setter.Value>
                                                                        <SolidColorBrush>#FF27C7F7</SolidColorBrush>
                                                                    </Setter.Value>
                                                                </Setter>
                                                                <Setter Property="Shape.Fill" TargetName="ExpandPath">
                                                                    <Setter.Value>
                                                                        <SolidColorBrush>#FFCCEEFB</SolidColorBrush>
                                                                    </Setter.Value>
                                                                </Setter>
                                                            </Trigger>
                                                            <MultiTrigger>
                                                                <MultiTrigger.Conditions>
                                                                    <Condition Property="UIElement.IsMouseOver" Value="True"/>
                                                                    <Condition Property="ToggleButton.IsChecked" Value="True"/>
                                                                </MultiTrigger.Conditions>
                                                                <Setter Property="Shape.Stroke" TargetName="ExpandPath">
                                                                    <Setter.Value>
                                                                        <SolidColorBrush>#FF1CC4F7</SolidColorBrush>
                                                                    </Setter.Value>
                                                                </Setter>
                                                                <Setter Property="Shape.Fill" TargetName="ExpandPath">
                                                                    <Setter.Value>
                                                                        <SolidColorBrush>#FF82DFFB</SolidColorBrush>
                                                                    </Setter.Value>
                                                                </Setter>
                                                            </MultiTrigger>
                                                        </ControlTemplate.Triggers>
                                                    </ControlTemplate>
                                                </Setter.Value>
                                            </Setter>
                                        </Style>
                                    </ToggleButton.Style>
                                </ToggleButton>
                                <Border BorderThickness="TemplateBinding Border.BorderThickness"
                                        Padding="TemplateBinding Control.Padding"
                                        BorderBrush="TemplateBinding Border.BorderBrush"
                                        Background="TemplateBinding Panel.Background"
                                        Name="Bd"
                                        SnapsToDevicePixels="True"
                                        Grid.Column="1">
                                    <ContentPresenter Content="TemplateBinding HeaderedContentControl.Header"
                                                      ContentTemplate="TemplateBinding HeaderedContentControl.HeaderTemplate"
                                                      ContentStringFormat="TemplateBinding HeaderedItemsControl.HeaderStringFormat"
                                                      ContentSource="Header"
                                                      Name="PART_Header"
                                                      HorizontalAlignment="TemplateBinding Control.HorizontalContentAlignment"
                                                      SnapsToDevicePixels="TemplateBinding UIElement.SnapsToDevicePixels" />
                                </Border>
                                <ItemsPresenter Name="ItemsHost"
                                                Grid.Column="1"
                                                Grid.Row="1"
                                                Grid.ColumnSpan="2" />
                            </Grid>
                            <ControlTemplate.Triggers>
                                <Trigger Property="TreeViewItem.IsExpanded" Value="False">
                                    <Setter Property="UIElement.Visibility" TargetName="ItemsHost" Value="Collapsed"/>
                                </Trigger>
                                <Trigger Property="ItemsControl.HasItems" Value="False">
                                    <Setter Property="UIElement.Visibility" TargetName="Expander" Value="Hidden"/>
                                </Trigger>
                                <Trigger Property="TreeViewItem.IsSelected" Value="True">
                                    <Setter Property="Panel.Background" TargetName="Bd">
                                        <Setter.Value>
                                            <DynamicResource ResourceKey="x:Static SystemColors.HighlightBrushKey" />
                                        </Setter.Value>
                                    </Setter>
                                    <Setter Property="TextElement.Foreground">
                                        <Setter.Value>
                                            <DynamicResource ResourceKey="x:Static SystemColors.HighlightTextBrushKey" />
                                        </Setter.Value>
                                    </Setter>
                                </Trigger>
                                <Trigger Property="UIElement.IsEnabled" Value="False">
                                    <Setter Property="TextElement.Foreground">
                                        <Setter.Value>
                                            <DynamicResource ResourceKey="x:Static SystemColors.GrayTextBrushKey" />
                                        </Setter.Value>
                                    </Setter>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </TreeView.ItemContainerStyle>
        <TreeViewItem Header="Item1"/>
        <TreeViewItem Header="Item2"/>
    </TreeView>

【讨论】:

成功了!!!!!!非常感谢 !!!我没有足够的声望给你投票。对不起…… 没问题 S.K.很高兴帮助..!! P.S,我通过在选择时将前景色涂成黑色来解决前景色问题。 这对我有用(就颜色而言),除了切换按钮不再打开该项目。 :-( 所以我将 ToggleButton 上的 IsChecked 更改为 IsChecked="Binding IsExpanded, RelativeSource=RelativeSource TemplatedParent" 现在它可以工作了。

以上是关于选择但失去焦点时更改 WPF treeViewItem 背景颜色的主要内容,如果未能解决你的问题,请参考以下文章

当项目更改时,CoreData 绑定的 NSTableView 会失去输入焦点,但前提是已排序

WPF,通过修改dataGrid的cell的style,改变选中行失去焦点时的颜色 4.0可用

按 T​​ab 时 NSTextField 没有注意到失去焦点?

Angular2动态输入字段在输入更改时失去焦点

WPF虚拟键盘如何不获得当前焦点

如何在文本更改时启用/禁用绑定到 ICommand 的按钮,而不是失去 TextBox 的焦点