This is a migrated thread and some comments may be shown as answers.

Change Text color of selected TreeViewItem only

6 Answers 2107 Views
TreeView
This is a migrated thread and some comments may be shown as answers.
Steve
Top achievements
Rank 1
Steve asked on 18 Mar 2015, 03:26 PM
Hi

I'm currently testing the UI for WPF and there's one problem I can't seem to solve. I wrote a small APF application using the Windows8-Theme. I change some Fonts, Font sizes and Colors of the palette and apply it as my application theme in the Code Behind.

Now I've got a TreeView where I'm dynamically adding children. This works as intended so far, but when an item in the TreeView is selected, the background color of the Selection-Border is blue (which is fine) but the font color is still black, which makes the name of the selected item hard to read.

So I tried to change the Foreground-Property of the currently selected item. There are two ways I tried out yet. First, I tried to change the style via XML by binding a style with a trigger to the ItemContainerStyle property of the TreeView, like this:

<telerik:RadTreeView ItemContainerStyle="{StaticResource SelectedTreeViewItem}" x:Name="TreeViewDomain">

And this is the Resource for the style:

<Style x:Key="SelectedTreeViewItem" TargetType="{x:Type telerik:RadTreeViewItem}">
      <Style.Triggers>
          <Trigger Property="IsSelected" Value="true">
              <Setter Property="Foreground" Value="White"/>
          </Trigger>
      </Style.Triggers>
</Style>

It kind of does the job but only kind of, because it also changes the Foreground color of all child elements of the selected item. I don't know if I did anything wrong there or if forgot something (I'm still fairly new to WPF) but this is not the behavior I expected.

I tried another approach: good old event driven Code Behind. Just change the Foreground color of the sender when the PreviewSelected event fired:

void __childItem_PreviewSelected(object sender, Telerik.Windows.RadRoutedEventArgs e)
{
    var __currentNode = (RadTreeViewItem) sender;
    __currentNode.Foreground = Brushes.White;
}

But same problem here: the Font color of the selected item changes, but so does the font color of all child items. I first thought this had something to do with event routing but that seems not to be the case. Since I'm adding children dynamically with Code Behind, I tried changing the Foreground color first and then added the child nodes but with the same result. They somehow seem to inherit the Foreground color of the parent.

Now I know that since I'm using the Windows8 Theme that I could make a local copy of the Theme-XAML, reference this one instead of the standard ones in the GAC from Telerik and change the color directly there. But I'm still curious as to why the control is behaving in they way I'm experiencing it in this case.

Any suggestions?

Regards,
Steve.

6 Answers, 1 is accepted

Sort by
0
Evgenia
Telerik team
answered on 21 Mar 2015, 09:22 AM
Hi Steve,

I'll start by saying that this might seem quite easy task - to change the Foreground of RadTreeViewItem-s on Selection. However it requires that you are known of some RadTreeView and Framework specifics. I'll try to explain them below:
1. You can apply implicit style for all RadTreeViewItem-s i.e. create a style without x:Key in your usercontrol resources. This style will be inherited through the hierarchy with dynamic items thanks to the HierarchicalDataTemplate. You are free to break the inheritance, when needed, by using multiple nested HierarchicalDataTemplates and by setting the ItemContainerStyle property of each of them.

2. Implicit styles are with high precedence than Style Triggers. (please refer to Dependency property precedence as stated by Microsoft in msdn ). To overcome this I suggest that you retemplate RadTreeViewItem style so that you change Selected Visual State to animate the Foreground with desired White color.

P.S. You can find a sample attached that demonstrates how to achieve your requirement. It uses our Implicit Styles theming mechanism. We highly recommend our customers to use it over StyleManager. You can read more about it from our documentation, more specifically here.

Let me know if there is anything else I can assist you with.

Regards,
Evgenia
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Steve
Top achievements
Rank 1
answered on 23 Mar 2015, 02:33 PM
Hi Evgenia,

thanks for your tips and your included sample. I knew about the Implicit Styles and just wanted to avoid the topic at first because it seems, at least in this case, rather complicated to me. Since I'm new to WPF, rummaging through this huge XAML Theme file seemed not to be the best solution.

Nevertheless I tried your approach and succeeded in recreating it in my own project. At first I was surprised by the amount of XAML code in your MainWindow.xaml but I saw that you just Copy&Pasted the XAML for the control from the Theme file. So I added the necessary files to my project as resources and edited the animation within them.

Now this is fine and it looks the way I want it to (see attached screenshot) but I'm still a little bit afraid of the huge XAML templates and finding and changing things within them - in this case, you showed me the right places, but I can hardly ask you every time :)

I know that you can create own styles that are based on the default template (like it was done in the documentation here). As far as I understood, this is what you described in your point 1. How can I achieve the white foreground with this way, using my own style that's based on the default (Windows8) theme? I still don't quite understand the concept behind the HierarchicalDataTemplates and the inheritance here. Could you give me an example?

Thanks in advance,
Steve.



0
Steve
Top achievements
Rank 1
answered on 23 Mar 2015, 02:57 PM
The RadListBoxItem is an example where it works like I charm. I wanted the same behavior here (white foreground when selected), and I just added a Style to my application resources like this:

<Style TargetType="{x:Type telerik:RadListBoxItem}" BasedOn="{StaticResource RadListBoxItemStyle}">
  <Style.Triggers>
    <Trigger Property="IsSelected" Value="true">
      <Setter Property="Foreground" Value="White"/>
    </Trigger>
  </Style.Triggers>
</Style>

I know it works here because there's no inheritance like in the TreeView. But this is basically my question: Can I do something like this for the TreeViewItems or do I need to edit the default template?

Regards,
Steve.
0
Evgenia
Telerik team
answered on 25 Mar 2015, 03:32 PM
Hi Steve,

You are right - RadTreeView is quite different than RadListBox due to the complex style properties inheritance it supports. Let me shed some more light on how this inheritance works in RadTreeView. First level RadTreeView Items inherit their styling from RadTreeView while their children (if they have child TreeViewItems) inherit theirs from their direct ascendant TreeViewItem.  
This can be easily observed with Style Trigger - since RadTreeViewItem-s does not have explicitly set Foreground in our themes - they inherit the Foreground they get from their parent TreeViewItem. When you select such parent TreeViewItem all its descendants become White like they are selected. You might observe the way Foreground property gets Inherited with XAML inspection tools like WPF Inspector or Snoop.
If you look at the dependency property setting precedence list given by Microsoft you will see that Inheritance has lower priority than Style Triggers or Implicit Style. It is up to you to decide whether to edit the default template of the control and apply the new template as implicit style or to use Trigger to achieve the desired effect on selection. If you choose to do this with Style Trigger you should add Setter that explicitly sets the Foreground of the TreeViewItem to Black like this:

<Style TargetType="{x:Type telerik:RadTreeViewItem}" BasedOn="{StaticResource RadTreeViewItemStyle}">
           <Setter Property="Foreground" Value="Black" />
           <Style.Triggers>
               <Trigger Property="IsSelected" Value="True">
                   <Setter Property="Foreground" Value="Red"/>
               </Trigger>
           </Style.Triggers>
       </Style>

I hope this information helps.

Regards,
Evgenia
Telerik
 

See What's Next in App Development. Register for TelerikNEXT.

 
0
Michael
Top achievements
Rank 1
answered on 13 Aug 2019, 02:27 PM
Is there a way to make the RadTreeViewItem text red if its name ends in ".dwg"?  I'm trying to highlight .dwg files in my TreeListView.  Thanks.
0
Martin Ivanov
Telerik team
answered on 16 Aug 2019, 08:09 AM

Hello Michael,

To achieve your requirement, you can use an IValueConverter that checks the file extension from the model of the item and returns a different color based on its value. Here is an example in code:

public class TreeItemModel
{
	public string FilePath { get; set; }
	public string FileExtension { get; set; }
}

public class ExtensionToBackgroundConverter : IValueConverter
{
	public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
	{
		var extension = (string)value;
		return extension == "dwg" ? Brushes.Red : null; // null or a default brush
	}

	public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
	{
		throw new NotImplementedException();
	}
}

<!-- Set the BasedOn property only if you use NoXaml dlls - BasedOn="{StaticResource RadTreeViewItemStyle}" -->
<!-- https://docs.telerik.com/devtools/wpf/styling-and-appearance/xaml-vs-noxaml -->
<Window.Resources>
	<local:ExtensionToBackgroundConverter x:Key="ExtensionToBackgroundConverter" />
	<Style TargetType="telerik:RadTreeViewItem" >
	   <Setter Property="Background" Value="{Binding FileExtension, Converter={StaticResource ExtensionToBackgroundConverter}}" />
	</Style>
</Window.Resources>

Regards, Martin Ivanov
Progress Telerik

Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
Tags
TreeView
Asked by
Steve
Top achievements
Rank 1
Answers by
Evgenia
Telerik team
Steve
Top achievements
Rank 1
Michael
Top achievements
Rank 1
Martin Ivanov
Telerik team
Share this question
or