WPF TreeView:如何像在资源管理器中一样使用圆角设置所选项目的样式
WPF TreeView 中的所选项目具有带有“尖”角的深蓝色背景。今天看起来有点过时:
我想将背景更改为在资源管理器中的样子Windows 7 的(有/无焦点):
到目前为止我所尝试的并没有删除原始的深蓝色背景,而是在其顶部绘制了一个圆形边框,以便您在边缘看到深蓝色,并且在左边-丑陋。
有趣的是,当我的版本没有焦点时,它看起来还不错:
我不想将控件模板重新定义为 显示此处或此处。我想设置最少必需的属性,以使所选项目看起来像在资源管理器中。
替代方案:我也很高兴让焦点选定的项目看起来像我现在没有焦点时的样子。失去焦点时,颜色应从蓝色变为灰色。
这是我的代码:
<TreeView
x:Name="TreeView"
ItemsSource="{Binding TopLevelNodes}"
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Recycling">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="BorderBrush" Value="#FF7DA2CE" />
<Setter Property="Background" Value="#FFCCE2FC" />
</Trigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type viewmodels:ObjectBaseViewModel}" ItemsSource="{Binding Children}">
<Border Name="ItemBorder" CornerRadius="2" Background="{Binding Background, RelativeSource={RelativeSource AncestorType=TreeViewItem}}"
BorderBrush="{Binding BorderBrush, RelativeSource={RelativeSource AncestorType=TreeViewItem}}" BorderThickness="1">
<StackPanel Orientation="Horizontal" Margin="2">
<Image Name="icon" Source="/ExplorerTreeView/Images/folder.png"/>
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</Border>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
解决方案
有了 Sheridan 和 Meleak 的出色回答,我的 TreeView 现在在代码中看起来像这样(我对此结果非常满意,并且非常接近 Explorer 的风格):
<TreeView
...
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<!-- Style for the selected item -->
<Setter Property="BorderThickness" Value="1"/>
<Style.Triggers>
<!-- Selected and has focus -->
<Trigger Property="IsSelected" Value="True">
<Setter Property="BorderBrush" Value="#7DA2CE"/>
</Trigger>
<!-- Mouse over -->
<Trigger Property="helpers:TreeView_IsMouseDirectlyOverItem.IsMouseDirectlyOverItem" Value="True">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFFAFBFD" Offset="0"/>
<GradientStop Color="#FFEBF3FD" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush" Value="#B8D6FB"/>
</Trigger>
<!-- Selected but does not have the focus -->
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="True"/>
<Condition Property="IsSelectionActive" Value="False"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" Value="#D9D9D9"/>
</MultiTrigger>
</Style.Triggers>
<Style.Resources>
<Style TargetType="Border">
<Setter Property="CornerRadius" Value="2"/>
</Style>
</Style.Resources>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type viewmodels:ObjectBaseViewModel}" ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal" Margin="2,1,5,2">
<Grid Margin="0,0,3,0">
<Image Name="icon" Source="/ExplorerTreeView/Images/folder.png"/>
</Grid>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>
<!-- Brushes for the selected item -->
<LinearGradientBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFDCEBFC" Offset="0"/>
<GradientStop Color="#FFC1DBFC" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="{x:Static SystemColors.ControlBrushKey}" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFF8F8F8" Offset="0"/>
<GradientStop Color="#FFE5E5E5" Offset="1"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="Black" />
</TreeView.Resources>
</TreeView>
The selected item in a WPF TreeView has a dark blue background with "sharp" corners. That looks a bit dated today:
I would like to change the background to look like in Explorer of Windows 7 (with/without focus):
What I tried so far does not remove the original dark blue background but paints a rounded border on top of it so that you see the dark blue color at the edges and at the left side - ugly.
Interestingly, when my version does not have the focus, it looks pretty OK:
I would like to refrain from redefining the control template as shown here or here. I want to set the minimum required properties to make the selected item look like in Explorer.
Alternative: I would also be happy to have the focused selected item look like mine does now when it does not have the focus. When losing the focus, the color should change from blue to grey.
Here is my code:
<TreeView
x:Name="TreeView"
ItemsSource="{Binding TopLevelNodes}"
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Recycling">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="BorderBrush" Value="#FF7DA2CE" />
<Setter Property="Background" Value="#FFCCE2FC" />
</Trigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type viewmodels:ObjectBaseViewModel}" ItemsSource="{Binding Children}">
<Border Name="ItemBorder" CornerRadius="2" Background="{Binding Background, RelativeSource={RelativeSource AncestorType=TreeViewItem}}"
BorderBrush="{Binding BorderBrush, RelativeSource={RelativeSource AncestorType=TreeViewItem}}" BorderThickness="1">
<StackPanel Orientation="Horizontal" Margin="2">
<Image Name="icon" Source="/ExplorerTreeView/Images/folder.png"/>
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</Border>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
Solution
With the excellent answers of Sheridan and Meleak my TreeView now looks like this in code (a result I am very happy with and which is pretty near Explorer's style):
<TreeView
...
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<!-- Style for the selected item -->
<Setter Property="BorderThickness" Value="1"/>
<Style.Triggers>
<!-- Selected and has focus -->
<Trigger Property="IsSelected" Value="True">
<Setter Property="BorderBrush" Value="#7DA2CE"/>
</Trigger>
<!-- Mouse over -->
<Trigger Property="helpers:TreeView_IsMouseDirectlyOverItem.IsMouseDirectlyOverItem" Value="True">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFFAFBFD" Offset="0"/>
<GradientStop Color="#FFEBF3FD" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush" Value="#B8D6FB"/>
</Trigger>
<!-- Selected but does not have the focus -->
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="True"/>
<Condition Property="IsSelectionActive" Value="False"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" Value="#D9D9D9"/>
</MultiTrigger>
</Style.Triggers>
<Style.Resources>
<Style TargetType="Border">
<Setter Property="CornerRadius" Value="2"/>
</Style>
</Style.Resources>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type viewmodels:ObjectBaseViewModel}" ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal" Margin="2,1,5,2">
<Grid Margin="0,0,3,0">
<Image Name="icon" Source="/ExplorerTreeView/Images/folder.png"/>
</Grid>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>
<!-- Brushes for the selected item -->
<LinearGradientBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFDCEBFC" Offset="0"/>
<GradientStop Color="#FFC1DBFC" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="{x:Static SystemColors.ControlBrushKey}" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFF8F8F8" Offset="0"/>
<GradientStop Color="#FFE5E5E5" Offset="1"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="Black" />
</TreeView.Resources>
</TreeView>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
添加到@Sheridan 的答案
这不是 100% 准确,但应该可以让您非常接近(它使用来自
GridView
的颜色,这与 Windows 资源管理器非常接近)Adding to @Sheridan's answer
This isn't a 100% accurate but should get you pretty close (it's using the colors from
GridView
which is pretty close to Windows Explorer)将其添加到您的
TreeView.ContainerStyle
中以删除默认的蓝色
背景。您可以将
黑色
替换为您想要的项目文本和所选项目文本的任何颜色。要在未聚焦时具有灰色背景,您可以设置带有灰色背景的“非聚焦”
Style
,并在TreeViewItem.GotFocus< 上使用
EventTrigger
。 /code> 和LostFocus
事件在Style
之间切换。编辑>>
如果您想要 Flash,您可以通过直接在
HierarchicalDataTemplate
中向ItemBorder Border
添加触发器来使用动画在背景颜色之间进行更改,如下所示:请注意,这只会如果
ColorAnimation
具有From
颜色,则有效。按照此代码,运行时将查找在Border.Background
属性上设置的SolidColorBrush
,因此您必须设置一个。您可以直接设置ColorAnimation.From
属性。Add this into your
TreeView.ContainerStyle
to remove the defaultblue
background.You can replace the
Black
with whatever colour you want your item text and selected item text to be.To have a grey background when not focused, you could set up a 'non focused'
Style
with a grey backgorund and useEventTrigger
s on theTreeViewItem.GotFocus
andLostFocus
events to switch between theStyle
s.EDIT>>>
If you want to be flash, you can use animations to change between the background colours by adding triggers to your
ItemBorder Border
directly in yourHierarchicalDataTemplate
like so:Note that this will only work if the
ColorAnimation
has aFrom
colour. As this code stands, the runtime will look for aSolidColorBrush
set on theBorder.Background
property, so you must set one. You could set theColorAnimation.From
property directly instead.Windows 10 TreeView (和 ListView) 样式
我最初是在寻找一种将 Windows 10 配色方案应用于 TreeViewItem 的方法,包括
如果你们中有人正在寻找这个,请随意使用下面的代码。我使用 Helge Klein 的解决方案来解决 IsMouseOver 问题,并将 Windows 10 颜色应用到 XAML。因此,我建议将此作为已接受答案的补充。
另外,请参阅下面有关
ListView
和ComboBox
的说明。屏幕截图
App.xaml
TreeViewItemHelper(作者:Helge Klein,细微更改/简化)
ListBox/ListView 和 ComboBox:在 Windows 7(和 8?) 中,这将导致从 TreeView 到 ListBox/ListView 和 ComboBox 的设计有所不同。因此,如果您也想将此配色方案应用于这些控件类型,请使用:
Windows 10 TreeView (and ListView) Style
I was originally looking for a way to apply the Windows 10 color scheme to a TreeViewItem, including
If any of you are looking for exactly this, please feel free to take the code below. I used Helge Klein's solution for the IsMouseOver issue and applied the Windows 10 colors to the XAML. Therefore I propose this as an addition to the accepted answer.
Also, see below for a word on
ListView
andComboBox
as well.Screenshot
App.xaml
TreeViewItemHelper (by Helge Klein, minor changes / simplification)
ListBox/ListView and ComboBox: In Windows 7 (and 8?), this will cause the design from TreeView to ListBox/ListView and ComboBox to differ. Therefore, if you want to apply this color scheme to these control types as well, too, use this: