Change Text color of selected TreeViewItem only

5 posts, 0 answers
  1. Steve
    Steve avatar
    17 posts
    Member since:
    Oct 2014

    Posted 18 Mar 2015 Link to this post

    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.
  2. Evgenia
    Admin
    Evgenia avatar
    1407 posts

    Posted 21 Mar 2015 Link to this post

    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.

     
  3. UI for WPF is Visual Studio 2017 Ready
  4. Steve
    Steve avatar
    17 posts
    Member since:
    Oct 2014

    Posted 23 Mar 2015 in reply to Evgenia Link to this post

    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.



  5. Steve
    Steve avatar
    17 posts
    Member since:
    Oct 2014

    Posted 23 Mar 2015 Link to this post

    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.
  6. Evgenia
    Admin
    Evgenia avatar
    1407 posts

    Posted 25 Mar 2015 Link to this post

    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.

     
Back to Top
UI for WPF is Visual Studio 2017 Ready