В настоящее время я использую довольно сложный метод шаблонирования / стилизации элемента управления WPF TreeView. Он состоит из 3 стилей, один для TreeView, один для TreeViewItem и один для ToggleButton. У меня все отлично работало, пока я не подумал, что будет крутой идеей представить некоторые настраиваемые свойства зависимостей в TreeView. Несколько из них включают ItemBackgroundBrush, ItemHighlightBrush и ItemSelectedBrush. Таким образом, вы можете определить или изменить каждое из этих значений при работе с разметкой TreeView вместо того, чтобы постоянно менять шаблоны (которые хранятся в словаре ресурсов). У меня есть все мои кисти, влияющие на ToggleButton, метко названный TreeViewToggle и проходящий через привязку к визуальному дереву. Причина этого в том, что IsMouseOver TreeViewitem имеет значение true, даже когда указатель мыши находится над одним из дочерних элементов элемента, это, я полагаю, связано с тем, что его ItemsPanel все еще технически является частью элемента. Чтобы обойти это, я обрабатываю триггер IsMouseOver TreeViewToggle, так что кисти наведения / выделения применяются к соответствующим заголовкам. Я предполагаю, что выложу код ниже, чтобы дать вам представление о том, что я делаю, но я предупреждаю вас, это становится чертовски большим, лол. Все работает до тех пор, пока не будет запущен IsMouseOver триггера TreeViewToggleStyle .. Я перешагнул через свойство кисти Highlight и в нем содержится кисть, переданная из свойства TreeViewEx ItemHighlightBackground, но я не могу на всю жизнь заставить его установить границу Свойство background LayoutRoot) ... (текущий установочный код - только одна из множества попыток использования различных синтаксисов привязки). Я пробовал так много примеров самосвязывания, которые я видел в Интернете, и ни один из них, похоже, не работает: (Опять же, извините за огромный пост, но я не был уверен, какая информация будет актуальна, а какая нет.
Заранее спасибо,
Райан.
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:my="clr-namespace:WpfApplication2">
<PathGeometry x:Key="TreeArrow" Figures="M0,0 L0,6 L6,0 z"/>
<Style x:Key="TreeViewToggleStyle" TargetType="{x:Type my:TreeViewToggle}">
<Setter Property="Focusable" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type my:TreeViewToggle}">
<Border x:Name="LayoutBorder"
CornerRadius="2"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<Path x:Name="Expander" Stroke="#FF989898" Data="{StaticResource TreeArrow}">
<Path.RenderTransform>
<RotateTransform Angle="135" CenterY="6" CenterX="3"/>
</Path.RenderTransform>
</Path>
<ContentPresenter x:Name="PART_Content" Margin="12,0,0,0" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="HasItems" Value="False">
<Setter TargetName="Expander" Property="Visibility" Value="Collapsed"/>
<Setter TargetName="PART_Content" Property="Margin" Value="0"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{Binding Path=HighlightBrush, RelativeSource={RelativeSource Mode=Self}}"/>
<Setter Property="BorderBrush" Value="{Binding Path=HighlightBorderBrush}"/>
<Setter Property="BorderThickness" Value="{Binding Path=HighlightBorderThickness}"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="RenderTransform" TargetName="Expander">
<Setter.Value>
<RotateTransform Angle="180" CenterY="5" CenterX="4"/>
</Setter.Value>
</Setter>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="False"/>
<Condition Property="IsMouseOver" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Stroke" TargetName="Expander" Value="#FF1BBBFA"/>
<Setter Property="Fill" TargetName="Expander" Value="Transparent"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="True"/>
<Condition Property="IsMouseOver" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Stroke" TargetName="Expander" Value="#FF1BBBFA"/>
<Setter Property="Fill" TargetName="Expander" Value="#FF1BBBFA"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="SolaceTreeViewItemStyle" TargetType="{x:Type TreeViewItem}">
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeViewItem}">
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<my:TreeViewToggle x:Name="PART_Expander"
ClickMode="Press"
ContentTemplate="{TemplateBinding HeaderTemplate}"
Content="{TemplateBinding Header}"
HasItems="{Binding HasItems, RelativeSource={RelativeSource TemplatedParent}}"
IsChecked="{Binding IsExpanded, RelativeSource={RelativeSource TemplatedParent}}"
IsSelected="{Binding IsSelected, RelativeSource={RelativeSource TemplatedParent}}"
Style="{DynamicResource TreeViewToggleStyle}"
Background="{Binding ItemBackground, RelativeSource={RelativeSource AncestorType={x:Type my:TreeViewEx}}}"
BorderBrush="{Binding ItemBorderBrush, RelativeSource={RelativeSource AncestorType={x:Type my:TreeViewEx}}}"
BorderThickness="{Binding ItemBorderThickness, RelativeSource={RelativeSource AncestorType={x:Type my:TreeViewEx}}}"
HighlightBrush="{Binding ItemHighlightBackground, RelativeSource={RelativeSource AncestorType={x:Type my:TreeViewEx}}}"
HighlightBorderBrush="{Binding ItemHighlightBorderBrush, RelativeSource={RelativeSource AncestorType={x:Type my:TreeViewEx}}}"
HighlightBorderThickness="{Binding ItemHighlightBorderThickness, RelativeSource={RelativeSource AncestorType={x:Type my:TreeViewEx}}}"
SelectedBrush="{Binding ItemSelectedBackground, RelativeSource={RelativeSource AncestorType={x:Type my:TreeViewEx}}}"
SelectedBorderBrush="{Binding ItemSelectedBorderBrush, RelativeSource={RelativeSource AncestorType={x:Type my:TreeViewEx}}}"
SelectedBorderThickness="{Binding ItemSelectedBorderThickness, RelativeSource={RelativeSource AncestorType={x:Type my:TreeViewEx}}}"/>
<ItemsPresenter x:Name="PART_Items" Grid.Row="1" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasItems" Value="False">
<Setter TargetName="PART_Items" Property="Visibility" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsExpanded" Value="False">
<Setter TargetName="PART_Items" Property="Visibility" Value="Collapsed"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- TreeView style omitted as its very simple -->
</ResourceDictionary>
У меня также есть 2 предложения, определенные с их зависимыми свойствами:
public class TreeViewEx : TreeView
{
public Brush ItemBorderBrush
{
get { return (Brush)base.GetValue(ItemBorderBrushProperty); }
set { base.SetValue(ItemBorderBrushProperty, value); }
}
public Brush ItemBackground
{
get { return (Brush)base.GetValue(ItemBackgroundProperty); }
set { base.SetValue(ItemBackgroundProperty, value); }
}
public Double ItemBorderThickness
{
get { return (Double)base.GetValue(ItemBorderThicknessProperty); }
set { base.SetValue(ItemBorderThicknessProperty, value); }
}
public Brush ItemHighlightBorderBrush
{
get { return (Brush)base.GetValue(ItemBorderBrushProperty); }
set { base.SetValue(ItemBorderBrushProperty, value); }
}
public Brush ItemHighlightBackground
{
get { return (Brush)base.GetValue(ItemHighlightBackgroundProperty); }
set { base.SetValue(ItemHighlightBackgroundProperty, value); }
}
public Double ItemHighlightBorderThickness
{
get { return (Double)base.GetValue(ItemBorderThicknessProperty); }
set { base.SetValue(ItemBorderThicknessProperty, value); }
}
public Brush ItemSelectedBorderBrush
{
get { return (Brush)base.GetValue(ItemBorderBrushProperty); }
set { base.SetValue(ItemBorderBrushProperty, value); }
}
public Brush ItemSelectedBackground
{
get { return (Brush)base.GetValue(ItemSelectedBackgroundProperty); }
set { base.SetValue(ItemSelectedBackgroundProperty, value); }
}
public Double ItemSelectedBorderThickness
{
get { return (Double)base.GetValue(ItemBorderThicknessProperty); }
set { base.SetValue(ItemBorderThicknessProperty, value); }
}
public static readonly DependencyProperty ItemBorderBrushProperty =
DependencyProperty.Register("ItemBorderBrush",
typeof(Brush),
typeof(TreeViewEx),
new PropertyMetadata(null));
public static readonly DependencyProperty ItemBorderThicknessProperty =
DependencyProperty.Register("ItemBorderThickness",
typeof(Double),
typeof(TreeViewEx),
new PropertyMetadata(1D));
public static readonly DependencyProperty ItemBackgroundProperty =
DependencyProperty.Register("ItemBackground",
typeof(Brush),
typeof(TreeViewEx),
new PropertyMetadata(null));
public static readonly DependencyProperty ItemHighlightBorderBrushProperty =
DependencyProperty.Register("ItemHighlightBorderBrush",
typeof(Brush),
typeof(TreeViewEx),
new PropertyMetadata(null));
public static readonly DependencyProperty ItemHighlightBorderThicknessProperty =
DependencyProperty.Register("ItemHighlightBorderThickness",
typeof(Double),
typeof(TreeViewEx),
new PropertyMetadata(1D));
public static readonly DependencyProperty ItemHighlightBackgroundProperty =
DependencyProperty.Register("ItemHighlightBackground",
typeof(Brush),
typeof(TreeViewEx),
new PropertyMetadata(null));
public static readonly DependencyProperty ItemSelectedBorderBrushProperty =
DependencyProperty.Register("ItemSelectedBorderBrush",
typeof(Brush),
typeof(TreeViewEx),
new PropertyMetadata(null));
public static readonly DependencyProperty ItemSelectedBorderThicknessProperty =
DependencyProperty.Register("ItemSelectedBorderThickness",
typeof(Double),
typeof(TreeViewEx),
new PropertyMetadata(1D));
public static readonly DependencyProperty ItemSelectedBackgroundProperty =
DependencyProperty.Register("ItemSelectedBackground",
typeof(Brush),
typeof(TreeViewEx),
new PropertyMetadata(SystemColors.HighlightBrush));
}
//this class was created to be used with the treeview control template
//it enables the passing of relevant information down the visual tree to sub-templates
//that perform extra layout duties based on data that the element doesn't natively support
public class TreeViewToggle : ToggleButton
{
public bool HasItems
{
get { return (bool)base.GetValue(HasItemsProperty); }
set { base.SetValue(HasItemsProperty, value); }
}
public bool IsSelected
{
get { return (bool)base.GetValue(IsSelectedProperty); }
set { base.SetValue(IsSelectedProperty, value); }
}
public Brush HighlightBrush
{
get { return (Brush)base.GetValue(HighlightBrushProperty); }
set { base.SetValue(HighlightBrushProperty, value); }
}
public Brush HighlightBorderBrush
{
get { return (Brush)base.GetValue(HighlightBorderBrushProperty); }
set { base.SetValue(HighlightBorderBrushProperty, value); }
}
public Double HighlightBorderThickness
{
get { return (Double)base.GetValue(HighlightBorderThicknessProperty); }
set { base.SetValue(HighlightBorderThicknessProperty, value); }
}
public Brush SelectedBrush
{
get { return (Brush)base.GetValue(SelectedBrushProperty); }
set { base.SetValue(SelectedBrushProperty, value); }
}
public Brush SelectedBorderBrush
{
get { return (Brush)base.GetValue(SelectedBorderBrushProperty); }
set { base.SetValue(SelectedBorderBrushProperty, value); }
}
public Double SelectedBorderThickness
{
get { return (Double)base.GetValue(SelectedBorderThicknessProperty); }
set { base.SetValue(SelectedBorderThicknessProperty, value); }
}
public static readonly DependencyProperty HasItemsProperty =
DependencyProperty.Register("HasItems",
typeof(bool),
typeof(TreeViewToggle));
public static readonly DependencyProperty IsSelectedProperty =
DependencyProperty.Register("IsSelected",
typeof(bool),
typeof(TreeViewToggle));
public static readonly DependencyProperty HighlightBrushProperty =
DependencyProperty.Register("HighlightBrush",
typeof(Brush),
typeof(TreeViewToggle),
new PropertyMetadata(null));
public static readonly DependencyProperty HighlightBorderBrushProperty =
DependencyProperty.Register("HighlightBorderBrush",
typeof(Brush),
typeof(TreeViewToggle),
new PropertyMetadata(null));
public static readonly DependencyProperty HighlightBorderThicknessProperty =
DependencyProperty.Register("HighlightBorderThickness",
typeof(Double),
typeof(TreeViewToggle),
new PropertyMetadata(1D));
public static readonly DependencyProperty SelectedBrushProperty =
DependencyProperty.Register("SelectedBrush",
typeof(Brush),
typeof(TreeViewToggle),
new PropertyMetadata(null));
public static readonly DependencyProperty SelectedBorderBrushProperty =
DependencyProperty.Register("SelectedBorderBrush",
typeof(Brush),
typeof(TreeViewToggle),
new PropertyMetadata(null));
public static readonly DependencyProperty SelectedBorderThicknessProperty =
DependencyProperty.Register("SelectedBorderThickness",
typeof(Double),
typeof(TreeViewToggle),
new PropertyMetadata(1D));
}