I need to set custom color for TreeViewControl in runtime so I need to add style in code. This is my tree control:
<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>
And when i'm building window with control i fire this method to add styles;
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;
}
}
I have tried with different methods, one like this:
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));
}
Could somebody provide me with any guidance? I feel lost right now because all other properties work. I can set text to be bold for example.
Thank you for reading this.
It's not working because you set the color of the TextBlock
statically to Blue
. It won't change by setting TreeViewItem.Foreground
.
Also don't create styles or templates in C#.
Don't explicitly set the TextBlock.Foreground
. Just set the TreeViewItem.Foreground
. By default Control.Foreground
will be inherited by child elements. This means the TextBlock.Foreground
will implicitly inherit the TreeViewItem.Foreground
.
Create a resource that serves as the binding source for the default Style
of the e.g., TreeViewItem
and add it to the application's ResourceDictionary
in the App.xaml. It should contain all dynamic properties of your layout e.g. colors, margins, font, font size etc.
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;
}