WPF 트리 표시:탐색기와 같이 모서리가 둥근 항목을 스타일링하는 방법
WPF Tree View에서 선택한 항목은 진한 파란색 배경에 "선명한" 모서리가 있습니다.그건 오늘 좀 오래된 것 같아.
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과 Mereak의 훌륭한 답변으로 Tree View는 다음과 같이 코드로 표시됩니다(그 결과 저는 매우 만족하며 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>
@Sheridan의 답변에 추가
100% 정확하지는 않지만 꽤 근접할 수 있을 것입니다.GridView
Windows 탐색기에 매우 근접합니다.)
<TreeView ...>
<TreeView.Resources>
<LinearGradientBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFD9F4FF" Offset="0"/>
<GradientStop Color="#FF9BDDFB" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="{x:Static SystemColors.ControlBrushKey}" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFEEEDED" Offset="0"/>
<GradientStop Color="#FFDDDDDD" Offset="1"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="Black" />
</TreeView.Resources>
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="BorderThickness" Value="1.5"/>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="BorderBrush" Value="#adc6e5"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="True"/>
<Condition Property="IsSelectionActive" Value="False"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" Value="LightGray"/>
</MultiTrigger>
</Style.Triggers>
<Style.Resources>
<Style TargetType="Border">
<Setter Property="CornerRadius" Value="2"/>
</Style>
</Style.Resources>
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
이것을 에 추가합니다.TreeView.ContainerStyle
디폴트를 삭제하다blue
배경.
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent" />
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="Black" />
</Style.Resources>
를 교환할 수 있습니다.Black
원하는 색상으로 아이템 텍스트와 선택한 아이템 텍스트가 표시됩니다.
초점을 맞추지 않을 때 회색 배경을 가지려면 '비집중'을 설정할 수 있습니다.Style
회색 백고런드와 함께 사용EventTrigger
에 있습니다.TreeViewItem.GotFocus
그리고.LostFocus
전환되는 이벤트Style
s.
편집>>>>
플래시가 되고 싶은 경우는, 애니메이션을 사용해, 트리거를 추가해 배경색을 변경할 수 있습니다.ItemBorder Border
에 직접HierarchicalDataTemplate
다음과 같이 합니다.
<Border.Triggers>
<EventTrigger RoutedEvent="Border.GotFocus">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" To="YourColour" Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Border.LostFocus">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" To="LightGray" Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Border.Triggers>
이것은, 다음의 경우에 한해 동작하는 것에 주의해 주세요.ColorAnimation
가 있다From
색칠을 합니다.이 코드가 존재하는 한 런타임은 다음 코드를 찾습니다.SolidColorBrush
에 설치하다.Border.Background
속성을 설정할 필요가 있습니다.를 설정할 수 있습니다.ColorAnimation.From
직접 등록해 주세요.
Windows 10 Tree View(및 List View) 스타일
Windows 10 의 색채 스킴을 Tree View 에 적용하는 방법을 찾고 있었습니다.다음을 포함한 항목
- 현재 항목에서만 IsMouseOver
- WPF가 이미 ListBox에 적용하고 있는 Windows 10 색상(Windows 탐색기 아님)
만약 이 코드를 찾으시는 분이 있다면, 아래의 코드를 부담없이 가져가세요.IsMouseOver 문제에서는 Helge Klein의 솔루션을 사용하여 Windows 10 컬러를 XAML에 적용하였기 때문에 답변에 추가해서 제안합니다.
에, 「 」, 「 」의 는, 을해 주세요.ListView
★★★★★★★★★★★★★★★★★」ComboBox
뿐만 아니라.
스크린샷
App.xaml
<Style TargetType="{x:Type TreeView}">
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="#CBE8F6" />
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="#F6F6F6" />
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="Black" />
</Style.Resources>
</Style>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="BorderThickness" Value="1" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="BorderBrush" Value="#26A0DA" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="local:TreeViewItemHelper.IsMouseDirectlyOverItem" Value="True" />
<Condition Property="IsSelected" Value="False" />
</MultiTrigger.Conditions>
<Setter Property="Background" Value="#E5F3FB" />
<Setter Property="BorderBrush" Value="#70C0E7" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="True" />
<Condition Property="IsSelectionActive" Value="False" />
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" Value="#DADADA" />
</MultiTrigger>
</Style.Triggers>
</Style>
트리뷰Item Helper (Helge Klein, 사소한 변경/심플화)
public static class TreeViewItemHelper
{
private static TreeViewItem CurrentItem;
private static readonly RoutedEvent UpdateOverItemEvent = EventManager.RegisterRoutedEvent("UpdateOverItem", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TreeViewItemHelper));
private static readonly DependencyPropertyKey IsMouseDirectlyOverItemKey = DependencyProperty.RegisterAttachedReadOnly("IsMouseDirectlyOverItem", typeof(bool), typeof(TreeViewItemHelper), new FrameworkPropertyMetadata(null, new CoerceValueCallback(CalculateIsMouseDirectlyOverItem)));
public static readonly DependencyProperty IsMouseDirectlyOverItemProperty = IsMouseDirectlyOverItemKey.DependencyProperty;
static TreeViewItemHelper()
{
EventManager.RegisterClassHandler(typeof(TreeViewItem), UIElement.MouseEnterEvent, new MouseEventHandler(OnMouseTransition), true);
EventManager.RegisterClassHandler(typeof(TreeViewItem), UIElement.MouseLeaveEvent, new MouseEventHandler(OnMouseTransition), true);
EventManager.RegisterClassHandler(typeof(TreeViewItem), UpdateOverItemEvent, new RoutedEventHandler(OnUpdateOverItem));
}
public static bool GetIsMouseDirectlyOverItem(DependencyObject obj)
{
return (bool)obj.GetValue(IsMouseDirectlyOverItemProperty);
}
private static object CalculateIsMouseDirectlyOverItem(DependencyObject item, object value)
{
return item == CurrentItem;
}
private static void OnUpdateOverItem(object sender, RoutedEventArgs e)
{
CurrentItem = sender as TreeViewItem;
CurrentItem.InvalidateProperty(IsMouseDirectlyOverItemProperty);
e.Handled = true;
}
private static void OnMouseTransition(object sender, MouseEventArgs e)
{
lock (IsMouseDirectlyOverItemProperty)
{
if (CurrentItem != null)
{
DependencyObject oldItem = CurrentItem;
CurrentItem = null;
oldItem.InvalidateProperty(IsMouseDirectlyOverItemProperty);
}
Mouse.DirectlyOver?.RaiseEvent(new RoutedEventArgs(UpdateOverItemEvent));
}
}
}
ListBox/ListView 및 ComboBox: Windows 7(및 8?)에서는 TreeView에서 ListBox/ListView 및 ComboBox로 설계가 달라집니다.따라서 이러한 제어 유형에도 이 색상표를 적용하려면 다음을 사용하십시오.
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border Name="Border" BorderThickness="1" Background="Transparent">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Border" Property="Background" Value="#E5F3FB" />
<Setter TargetName="Border" Property="BorderBrush" Value="#70C0E7" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Border" Property="Background" Value="#CBE8F6" />
<Setter TargetName="Border" Property="BorderBrush" Value="#26A0DA" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="True" />
<Condition Property="Selector.IsSelectionActive" Value="False" />
</MultiTrigger.Conditions>
<Setter TargetName="Border" Property="Background" Value="#F6F6F6" />
<Setter TargetName="Border" Property="BorderBrush" Value="#DADADA" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type ListViewItem}" BasedOn="{StaticResource {x:Type ListBoxItem}}" />
<Style TargetType="{x:Type ComboBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBoxItem}">
<Border Name="Border" BorderThickness="1" Padding="1" Background="Transparent">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Border" Property="Background" Value="#E5F3FB" />
<Setter TargetName="Border" Property="BorderBrush" Value="#70C0E7" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Border" Property="Background" Value="#CBE8F6" />
<Setter TargetName="Border" Property="BorderBrush" Value="#26A0DA" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
언급URL : https://stackoverflow.com/questions/5047576/wpf-treeview-how-to-style-selected-items-with-rounded-corners-like-in-explorer
'bestsource' 카테고리의 다른 글
프로그래밍 방식으로 버튼을 만들려면 어떻게 해야 합니다. (0) | 2023.04.24 |
---|---|
Windows 7 x 64에서는 Git Bash가 매우 느리다 (0) | 2023.04.19 |
태그는 Git 브랜치와 어떻게 다릅니까?여기 어떤 걸 쓰면 좋을까요? (0) | 2023.04.19 |
UIViewAlertForUnsatibleConstraints를 트랩하는 방법 (0) | 2023.04.19 |
Git - 코드를 두 개의 리모컨으로 푸시 (0) | 2023.04.19 |