从代码隐藏中为 TreeViewItem 设置前景色

Setting foreground color for TreeViewItem from code behind

我需要在运行时为 TreeViewControl 设置自定义颜色,所以我需要在代码中添加样式。 这是我的树控件:

<UserControl x:Class="Client.WPF.CommonControls.Controls.Common.Tree"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:local="clr-namespace:Client.WPF.CommonControls.Controls"
         xmlns:sf="http://schemas.syncfusion.com/wpf"
         xmlns:vm="clr-namespace:ClientCore.ViewModels;assembly=ClientCore"
         xmlns:models="clr-namespace:Client.WPF.CommonControls.Models"
         xmlns:metaInfos="clr-namespace:Base.MetaInfos;assembly=PresentationBase"
         mc:Ignorable="d" >

<UserControl.DataContext>
    <models:TreeViewModel></models:TreeViewModel>
</UserControl.DataContext>


<TreeView Name="TreeViewNodes" ItemsSource="{Binding TopNodes}" SelectedValuePath="{Binding SelectedStarElement}">
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate DataType="{x:Type metaInfos:Element}" ItemsSource="{Binding Children}">
            <TextBlock Text="{Binding Path=Caption}"
                       Foreground="Blue"
                       TextAlignment="Left"
                       HorizontalAlignment="Left"
                       VerticalAlignment="Center"
                       />
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

当我用控件构建 window 时,我会触发此方法来添加样式;

public void AdjustAppearance(Appearance appearance)
    {
        if (appearance!= null)
        {
            if (!appearance.BackColor.isEmpty)
            {
                Background = StyleHelper.GetSolidColor(appearance.BackColor);
                TreeViewNodes.Background = StyleHelper.GetSolidColor(appearance.BackColor);
            }
            else
            {
                Background = new SolidColorBrush(Colors.White);
                TreeViewNodes.Background = new SolidColorBrush(Colors.White);
            }

            if (!appearance.ForeColor.isEmpty)
            {
                Foreground = StyleHelper.GetSolidColor(appearance.ForeColor);
                TreeViewNodes.Foreground = StyleHelper.GetSolidColor(appearance.ForeColor);
            }

            if (!appearance.BorderColor.isEmpty)
            {
                BorderBrush = StyleHelper.GetSolidColor(appearance.BorderColor);
            }

            if (appearance.BorderThickness >= 0)
            {
                BorderThickness = new Thickness(appearance.BorderThickness);
            }

            if (appearance.ForeColor != null && !appearance.ForeColor.isEmpty)
            {
                //Foreground = StyleHelper.GetSolidColor(appearance.ForeColor);
                //TreeViewNodes.Foreground = StyleHelper.GetSolidColor(appearance.ForeColor);
                //StyleHelper.SetStyleForControlItemContainerStyle(
                //    this, typeof(TextBlock), TextBlock.ForegroundProperty, appearance.ForeColor);

                Style textStyle = new Style(typeof(TextBlock));
                textStyle.Setters.Add(new Setter(ForegroundProperty, StyleHelper.GetSolidColor(appearance.ForeColor)));
                TreeViewNodes.Resources.Add("textStyle", textStyle);

                //Foreground = new SolidColorBrush(Colors.Aqua);
                //StyleHelper.SetStyleForControlItemContainerStyle(
                //    this, typeof(TreeViewItemAdv), TreeViewItemAdv.ForegroundProperty, appearance.ForeColor);

            }
            if (appearance.FontData.SizeInPoints > 0)
            {
                FontSize = StyleHelper.PointsToPixels(appearance.FontData.SizeInPoints);
                TreeViewNodes.FontSize = StyleHelper.PointsToPixels(appearance.FontData.SizeInPoints);
            }

            if (!string.IsNullOrEmpty(appearance.FontData.Name))
            {
                FontFamily = new FontFamily(appearance.FontData.Name);
                TreeViewNodes.FontFamily = new FontFamily(appearance.FontData.Name);
            }

            this.FontWeight = appearance.FontData.Bold ? FontWeights.Bold : FontWeights.Normal;
            TreeViewNodes.FontWeight = appearance.FontData.Bold ? FontWeights.Bold : FontWeights.Normal;
            this.FontStyle = appearance.FontData.Italic ? FontStyles.Italic : FontStyles.Normal;
            TreeViewNodes.FontStyle = appearance.FontData.Italic ? FontStyles.Italic : FontStyles.Normal;
        }
    }

我尝试过不同的方法,其中一个是这样的:

    public static void SetStyleForControlItemContainerStyle(Control control, Type typeOfControl, DependencyProperty property, object value)
    {
        if (typeOfControl == null) return;
        var itemContainerStyle = (control as ItemsControl)?.ItemContainerStyle;
        if (itemContainerStyle == null) itemContainerStyle = new Style(typeOfControl);
        itemContainerStyle.Setters.Add(new Setter(property, value));
    }

有人可以为我提供任何指导吗?我现在感到迷茫,因为所有其他属性都有效。例如,我可以将文本设置为粗体。

感谢您阅读本文。

它不起作用,因为您将 TextBlock 的颜色静态设置为 Blue。设置TreeViewItem.Foreground.
不会改变 也不要在 C# 中创建样式或模板。

不要明确设置 TextBlock.Foreground。只需设置 TreeViewItem.Foreground。默认情况下 Control.Foreground 将被子元素继承。这意味着 TextBlock.Foreground 将隐式继承 TreeViewItem.Foreground.

创建一个资源作为默认 Style 的绑定源,例如 TreeViewItem,并将其添加到 中应用程序的 ResourceDictionaryApp.xaml。它应该包含布局的所有动态属性,例如颜色、边距、字体、字体大小等

ThemeProvider.cs

class ThemeProvider : DependencyObject
{
  public static readonly DependencyProperty TreeViewItemForegroundProperty = DependencyProperty.Register(
    "TreeViewItemForeground",
    typeof(Brush),
    typeof(ThemeProvider),
    new PropertyMetadata(Brushes.Blue));

  public Brush TreeViewItemForeground
  {
    get => (Brush) GetValue(ThemeProvider.TreeViewItemForegroundProperty);
    set => SetValue(ThemeProvider.TreeViewItemForegroundProperty, value);
  }
}

App.xaml

<Application>
  <Application.Resources>
    <ResourceDictionar>
      <ThemeProvider x:Key="ThemeProvider" />
    </ResourceDictionar>
  </Application.Resources>
<Application>

Tree.xaml

<TreeView Name="TreeViewNodes">
  <TreeView.ItemTemplate>
    <HierarchicalDataTemplate DataType="{x:Type metaInfos:Element}" ItemsSource="{Binding Children}">
      <TextBlock Text="{Binding Path=Caption}"
                 TextAlignment="Left"
                 HorizontalAlignment="Left"
                 VerticalAlignment="Center" />
    </HierarchicalDataTemplate>
  </TreeView.ItemTemplate>

  <TreeView.ItemContainerStyle>
    <Style TargetType="TreeViewItem">
      <Setter Property="Foreground" 
              Value="Binding Source={StaticResource ThemeProvider}, Path=TreeViewItemForeground}" />
    </Style>
  </TreeView.ItemContainerStyle>
</TreeView>

MainWindow.xaml.cs

private void AdjustAppearance(Appearance appearance)
{
  var themeProvider = Application.Current.Resources["ThemeProvider"] as ThemeProvider;
  themeProvider.TreeViewItemForeground = appearance.ForeColor;
}