设置在“自身”上触发从父模板 (WPF) 传递的属性

发布于 2024-10-31 13:05:59 字数 15386 浏览 0 评论 0原文

我目前正在使用一种相当复杂的方法来对 WPF TreeView 控件进行模板化/样式化。它由 3 种样式组成,一种用于 TreeView,一种用于 TreeViewItem,一种用于 ToggleButton。我一切都工作得很好,直到我认为在 TreeView 上公开一些自定义依赖属性是一个很酷的主意。其中包括 ItemBackgroundBrush、ItemHighlightBrush 和 ItemSelectedBrush。因此,您可以在使用 TreeView 标记时定义或更改每个值,而不必不断更改模板(存储在资源字典中)。我的所有画笔都会影响 ToggleButton,恰当地命名为 TreeViewToggle,并通过绑定传递到可视化树。这样做的原因是,即使鼠标指针位于该项目的子项之一上,TreeViewitem 的 IsMouseOver 也是 true,我想这是因为它的 ItemsPanel 在技术上仍然是该项目的一部分。为了超越这一点,我处理 TreeViewToggle 的 IsMouseOver 触发器,以便将悬停/选择画笔应用于适当的标题。我想我会发布下面的代码,让您了解我在做什么,但我警告您它变得非常大,哈哈。一切工作正常,直到 TreeViewToggleStyle 的 IsMouseOver 触发器。我已经跨过了高亮笔刷属性,它包含从 TreeViewEx ItemHighlightBackground 属性传递下来的笔刷,但我一生都无法将其设置为边框( 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));
}

I'm currently using a rather complex method of templating/styling the WPF TreeView control. This consists of 3 styles, one for the TreeView, one for the TreeViewItem, and one for a ToggleButton. I had everything working great until I thought it would be a cool idea to expose some customizing depedency properties on the TreeView. A couple of them include ItemBackgroundBrush, ItemHighlightBrush, and ItemSelectedBrush. So you can define or change each of these values while working with the TreeView markup instead of having to continuously change the templates (which are stored in a resource dictionary). I have all of my brushes affecting the ToggleButton, aptly named TreeViewToggle and passed via binding down the visual tree. The reason for this is that IsMouseOver of the TreeViewitem is true even when the mouse pointer is over one of the item's children, this I suppose is because it's ItemsPanel is still technically part of the item. To surpass this I handle the IsMouseOver trigger of the TreeViewToggle so hover/selection brushes are applied to the appropriate headers. I guess I'll post the code below to give you an idea of what I'm doing but I warn you it's getting pretty darn large lol. Everything works fine up until the IsMouseOver trigger of the TreeViewToggleStyle.. I've stepped over the Highlight brush property and it contains the brush passed down from the TreeViewEx ItemHighlightBackground property but I cannot for the life of me get it to set to the border (LayoutRoot)'s background property... (the current setter code is only one of many attempts at different binding sytaxes.. I have tried so many examples of self binding I've seen on the web and none of them seem to work :( Again, sorry for the huge post but I wasn't sure what information would be relevant and what wouldn't.
Thanks in advance,
Ryan.

<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>

I also have 2 clases defined with their dependency properties exposed:

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));
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

千年*琉璃梦 2024-11-07 13:05:59

您在 SolaceTreeViewItemStyle 的 ControlTemplate 中设置 TreeViewToggle 的 Background 属性,这意味着您在 TreeViewToggle 的 Style 中执行的任何操作都无法更改它。

这基于依赖属性值优先级(请参阅列表)。您的风格触发器位于 6,而显式设置位于 3,因此显式设置获胜。

您必须像这样设置边框的背景:

<Trigger Property="IsMouseOver" Value="True">
    <Setter TargetElement="LayoutBorder" Property="Background"
        Value="{Binding Path=HighlightBrush, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
    <Setter TargetElement="LayoutBorder" Property="BorderBrush"
        Value="{Binding Path=HighlightBorderBrush, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
    <Setter TargetElement="LayoutBorder" Property="BorderThickness"
        Value="{Binding Path=HighlightBorderThickness, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
</Trigger>

编辑:以下 ControlTemplate 应该允许您取消自定义 ToggleButton:

<ControlTemplate TargetType="{x:Type TreeViewItem}">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Grid x:Name="header">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" MinWidth="19" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>
            <ToggleButton x:Name="Expander" Style="{StaticResource ExpandCollapseToggleStyle}"
                    IsChecked="{Binding Path=IsExpanded,RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press" />
            <Border Name="Bd" Grid.Column="1" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"
                    BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
                <ContentPresenter x:Name="PART_Header" ContentSource="Header"
                        HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                        SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
            </Border>
        </Grid>
        <ItemsPresenter x:Name="ItemsHost" Grid.Row="1" Grid.Column="1" Margin="19,0,0,0" />
    </Grid>
    <ControlTemplate.Triggers>
        <Trigger SourceName="header" Property="IsMouseOver" Value="true">
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

you set the Background property of your TreeViewToggle in the ControlTemplate of your SolaceTreeViewItemStyle, so that means nothing you do in the TreeViewToggle's Style can change it.

This is based on the Dependency Property Value Precedence (see the list). Your Style trigger is at a 6, while the explicit setting is at a 3, so the explicit setting wins.

You would have to set the Background of the Border like this instead:

<Trigger Property="IsMouseOver" Value="True">
    <Setter TargetElement="LayoutBorder" Property="Background"
        Value="{Binding Path=HighlightBrush, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
    <Setter TargetElement="LayoutBorder" Property="BorderBrush"
        Value="{Binding Path=HighlightBorderBrush, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
    <Setter TargetElement="LayoutBorder" Property="BorderThickness"
        Value="{Binding Path=HighlightBorderThickness, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
</Trigger>

EDIT: The following ControlTemplate should allow you to do away with a custom ToggleButton:

<ControlTemplate TargetType="{x:Type TreeViewItem}">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Grid x:Name="header">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" MinWidth="19" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>
            <ToggleButton x:Name="Expander" Style="{StaticResource ExpandCollapseToggleStyle}"
                    IsChecked="{Binding Path=IsExpanded,RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press" />
            <Border Name="Bd" Grid.Column="1" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"
                    BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
                <ContentPresenter x:Name="PART_Header" ContentSource="Header"
                        HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                        SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
            </Border>
        </Grid>
        <ItemsPresenter x:Name="ItemsHost" Grid.Row="1" Grid.Column="1" Margin="19,0,0,0" />
    </Grid>
    <ControlTemplate.Triggers>
        <Trigger SourceName="header" Property="IsMouseOver" Value="true">
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文