微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

WPF TreeView更改ToggleButton的背景色

如何解决WPF TreeView更改ToggleButton的背景色

我有这个正在运行的用户控件xaml:

<UserControl ...>
 <TreeView Background="Yellow" ... >
    <TreeView.Resources >
        <HierarchicalDataTemplate ... >
            <Grid Name="Header" Background="Green" ... >
            </Grid>
        </HierarchicalDataTemplate>     

        <DataTemplate ... >
            <Grid Name="MultipleItems">
            </Grid>
        </DataTemplate>
    </TreeView.Resources>  
  </TreeView>
</UserControl>

我只需要更改TreeView切换按钮的背景颜色 类似于Grid标头的Green。切换按钮的认背景颜色类似于TreeView的黄色。

当我尝试在 TreeView 标记之后和 TreeView.Resources 标记之前添加这些代码时,遇到错误

<TreeViewItem>
   <TreeViewItem.Template>
      <ControlTemplate targettype="TreeViewItem">
         <Grid>
            <ToggleButton>
               <ToggleButton.Style>
                  <Style targettype="ToggleButton">
                     <Setter Property="Background" Value="Green"/>
                  </Style>
               </ToggleButton.Style>
            </ToggleButton>
         </Grid>
      </ControlTemplate>
   </TreeViewItem.Template>
</TreeViewItem>

错误“在使用ItemsSource之前,Items集合必须为空。” 。 如何成功更改切换按钮的背景颜色? 我上面的解决方法不正确吗?请告诉我是否还有其他方法 以及如何做到这一点。

其他信息: 即使添加此简单行,也会发生错误

<TreeViewItem></TreeViewItem>

解决方法

要更改控件的外观或视觉状态,必须更改其样式或控件模板。这些远远超出您的预期。像您提供的控件模板一样,缺少大多数状态和必需的部分(模板中的控件)才能正常工作。您可以查看所需的零件和状态in the documentation

您可以extract the default ones using Blend or Visual Studio并使它们适应您的需求,而不是从头开始为控件创建控件模板和样式。在大多数情况下,您将复制大量代码,并且满足您的要求所需的更改很小,但是没有其他方法,因为您无法像使用样式一样将控件模板基于其他控件模板。

错误是“在使用ItemsSource之前,Items集合必须为空。”

由于在TreeViewItem中设置了TreeView,因此出现此错误。它将把此项添加为内容,但是由于您可能已经在其他位置设置了ItemsSource,因此会引发错误,因为您不能同时执行这两项。相反,您可以通过ItemContainerStyle属性设置自定义样式,例如像这样的内联:

<TreeView ItemsSource="{Binding MyTreeViewNodes}">
   <TreeView.ItemContainerStyle>
      <Style TargetType="{x:Type TreeViewItem}">
         <Setter Property="Template">
            <Setter.Value>
               <ControlTemplate TargetType="TreeViewItem">
                  <!-- ...your control template -->
               </ControlTemplate>
            </Setter.Value>
         </Setter>
      </Style>
   </TreeView.ItemContainerStyle>
   <!-- ...other tree view definitions. -->
</TreeView>

当然,您也可以使用StaticResourceDynamicResource引用命名样式。希望您能理解,但无论哪种方式,您的控制模板都不完整,无法正常工作。

我已经提取了包括TreeViewItem的控制模板在内的默认样式,并对其进行了调整。您必须将所有这些样式复制到范围或应用程序资源中的资源字典中。

<SolidColorBrush x:Key="TreeViewItem.TreeArrow.Static.Background" Color="Green"/>
<SolidColorBrush x:Key="TreeViewItem.TreeArrow.Static.Stroke" Color="#FF818181"/>
<SolidColorBrush x:Key="TreeViewItem.TreeArrow.Static.Fill" Color="#FFFFFFFF"/>
<SolidColorBrush x:Key="TreeViewItem.TreeArrow.MouseOver.Background" Color="Green"/>
<SolidColorBrush x:Key="TreeViewItem.TreeArrow.MouseOver.Stroke" Color="#FF27C7F7"/>
<SolidColorBrush x:Key="TreeViewItem.TreeArrow.MouseOver.Fill" Color="#FFCCEEFB"/>
<SolidColorBrush x:Key="TreeViewItem.TreeArrow.Static.Checked.Background" Color="Green"/>
<SolidColorBrush x:Key="TreeViewItem.TreeArrow.Static.Checked.Stroke" Color="#FF262626"/>
<SolidColorBrush x:Key="TreeViewItem.TreeArrow.Static.Checked.Fill" Color="#FF595959"/>
<SolidColorBrush x:Key="TreeViewItem.TreeArrow.MouseOver.Checked.Background" Color="Green"/>
<SolidColorBrush x:Key="TreeViewItem.TreeArrow.MouseOver.Checked.Stroke" Color="#FF1CC4F7"/>
<SolidColorBrush x:Key="TreeViewItem.TreeArrow.MouseOver.Checked.Fill" Color="#FF82DFFB"/>
<PathGeometry x:Key="TreeArrow" Figures="M0,0 L0,6 L6,0 z"/>

<Style x:Key="ExpandCollapseToggleStyle" TargetType="{x:Type ToggleButton}">
   <Setter Property="Focusable" Value="False"/>
   <Setter Property="Width" Value="16"/>
   <Setter Property="Height" Value="16"/>
   <Setter Property="Template">
      <Setter.Value>
         <ControlTemplate TargetType="{x:Type ToggleButton}">
            <Border x:Name="ExpandBorder" Background="{StaticResource TreeViewItem.TreeArrow.Static.Background}" Height="16" Padding="5,5,5" Width="16">
               <Path x:Name="ExpandPath" Data="{StaticResource TreeArrow}" Fill="{StaticResource TreeViewItem.TreeArrow.Static.Fill}" Stroke="{StaticResource TreeViewItem.TreeArrow.Static.Stroke}">
                  <Path.RenderTransform>
                     <RotateTransform Angle="135" CenterY="3" CenterX="3"/>
                  </Path.RenderTransform>
               </Path>
            </Border>
            <ControlTemplate.Triggers>
               <Trigger Property="IsChecked" Value="True">
                  <Setter Property="RenderTransform" TargetName="ExpandPath">
                     <Setter.Value>
                        <RotateTransform Angle="180" CenterY="3" CenterX="3"/>
                     </Setter.Value>
                  </Setter>
                  <Setter Property="Fill" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.Static.Checked.Fill}"/>
                  <Setter Property="Stroke" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.Static.Checked.Stroke}"/>
                  <Setter Property="Background" TargetName="ExpandBorder" Value="{StaticResource TreeViewItem.TreeArrow.Static.Checked.Background}"/>
               </Trigger>
               <Trigger Property="IsMouseOver" Value="True">
                  <Setter Property="Stroke" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.MouseOver.Stroke}"/>
                  <Setter Property="Fill" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.MouseOver.Fill}"/>
                  <Setter Property="Background" TargetName="ExpandBorder" Value="{StaticResource TreeViewItem.TreeArrow.MouseOver.Background}"/>
               </Trigger>
               <MultiTrigger>
                  <MultiTrigger.Conditions>
                     <Condition Property="IsMouseOver" Value="True"/>
                     <Condition Property="IsChecked" Value="True"/>
                  </MultiTrigger.Conditions>
                  <Setter Property="Stroke" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.MouseOver.Checked.Stroke}"/>
                  <Setter Property="Fill" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.MouseOver.Checked.Fill}"/>
                  <Setter Property="Background" TargetName="ExpandBorder" Value="{StaticResource TreeViewItem.TreeArrow.MouseOver.Checked.Background}"/>
               </MultiTrigger>
            </ControlTemplate.Triggers>
         </ControlTemplate>
      </Setter.Value>
   </Setter>
</Style>

<Style x:Key="TreeViewItemFocusVisual">
   <Setter Property="Control.Template">
      <Setter.Value>
         <ControlTemplate>
            <Rectangle/>
         </ControlTemplate>
      </Setter.Value>
   </Setter>
</Style>

<Style x:Key="TreeViewItemContainerStyle" TargetType="{x:Type TreeViewItem}">
   <Setter Property="Background" Value="Transparent"/>
   <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment,RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
   <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment,RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
   <Setter Property="Padding" Value="1,0"/>
   <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
   <Setter Property="FocusVisualStyle" Value="{StaticResource TreeViewItemFocusVisual}"/>
   <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" ClickMode="Press" IsChecked="{Binding IsExpanded,RelativeSource={RelativeSource TemplatedParent}}" Style="{StaticResource ExpandCollapseToggleStyle}"/>
               <Border x:Name="Bd" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" Grid.Column="1" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
                  <ContentPresenter x:Name="PART_Header" ContentSource="Header" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
               </Border>
               <ItemsPresenter x:Name="ItemsHost" Grid.ColumnSpan="2" Grid.Column="1" Grid.Row="1"/>
            </Grid>
            <ControlTemplate.Triggers>
               <Trigger Property="IsExpanded" Value="false">
                  <Setter Property="Visibility" TargetName="ItemsHost" Value="Collapsed"/>
               </Trigger>
               <Trigger Property="HasItems" Value="false">
                  <Setter Property="Visibility" TargetName="Expander" Value="Hidden"/>
               </Trigger>
               <Trigger Property="IsSelected" Value="true">
                  <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                  <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" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
                  <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}}"/>
               </MultiTrigger>
               <Trigger Property="IsEnabled" Value="false">
                  <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
               </Trigger>
            </ControlTemplate.Triggers>
         </ControlTemplate>
      </Setter.Value>
   </Setter>
   <Style.Triggers>
      <Trigger Property="VirtualizingPanel.IsVirtualizing" Value="true">
         <Setter Property="ItemsPanel">
            <Setter.Value>
               <ItemsPanelTemplate>
                  <VirtualizingStackPanel/>
               </ItemsPanelTemplate>
            </Setter.Value>
         </Setter>
      </Trigger>
   </Style.Triggers>
</Style>

如您所见,这非常复杂。项目本身中有TreeViewItem的样式,焦点样式和ToggleButton的样式。我只改编了名为Border的{​​{1}}并为其分配了初始背景,具体取决于触发器中项目的状态。

如果要在不同状态下调整颜色,只需更改以下画笔即可:

  • ExpandBorder
  • TreeViewItem.TreeArrow.Static.Background
  • TreeViewItem.TreeArrow.MouseOver.Background
  • TreeViewItem.TreeArrow.Static.Checked.Background

要应用新的TreeViewItem.TreeArrow.MouseOver.Checked.Background样式,请将其引用为TreeViewItem

ItemContainerStyle

如果省略相应样式的键,则可以将样式应用于范围中的所有<TreeView ItemsSource="{Binding MyTreeViewNodes}" ItemContainerStyle="{StaticResource TreeViewItemContainerStyle}"> ,这使其成为隐式样式。

TreeViewItem
,

您的某些代码用省略号隐藏了,但我的猜测是,当已经指定了<TreeViewItem/>属性时,您正在尝试将TreeView.Items添加到TreeView.ItemSource。使用ItemsControl时,必须使用Items属性或ItemsSource属性。

请查看this 这样的答案以了解更多详细信息。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。