views:

8443

answers:

6

If I set TreeViewItem Background it highlights the header only. How can I highlight the whole line?

I have found a post almost solving a problem http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/b04f73e2-0b10-4d97-a6da-64df2e30c21d/

But there are some problems: 1. It does not highlight the whole line 2. The tree has XP style on Vista. I whould like it to looks the same way on Vista as it was, but if user changed the theme to XP - it should be XP way. 3. So many XAML...

Any ideas, what I should look for?

+2  A: 
bendewey
Thank you, Bendewey. But your solution highlights line after the toggle. I whould like it to highlight the whole line. Seems the Grid in the template will not allow this, don't you know any other solutions?
alex2k8
Its definately possible. I can rewrite something for you later tonight. but basically you'll want to change its from a grid to maybe a stackpanel and then put the expander icon inside the border. You'll also have to change the triggers.
bendewey
That would be great! As it is not clear for me, how we can indent nodes without c# if some thing like StackPanel used.
alex2k8
To indent nodes using the stackpanel I would use left Margin
bendewey
+1  A: 
bendewey
Thank you! But if you go to the child nodes, you'll notice white space to the left of the toggle. I want to select FULL line. Pseudo solution is: ItemsPresenter.margin="0", and ColumnDefinition Width="19 * Level". I tryed to use MarkupExension to compute Level - no luck. Any ideas?
alex2k8
+10  A: 
bendewey
That's it! Thank you VERY MUCH for all your posts!
alex2k8
A: 

Source of the problem when use TreeView with ItemsSource is , refered from link text, I have changed some code of TreeViewItemExtensions class:

public static class TreeViewItemExtensions
{
    public static int GetDepth(this TreeViewItem item)
    {
        while (GetSelectedTreeViewItemParent(item) != null)
        {
            var parent = GetSelectedTreeViewItemParent(item);
            if (parent != null)
                return parent.GetDepth() + 1;

            item = parent;
        }
        return 0;
 }

 public static TreeViewItem GetSelectedTreeViewItemParent(this TreeViewItem item)
 {
        DependencyObject parent = VisualTreeHelper.GetParent(item);
        while (!(parent is TreeViewItem || parent is TreeView))
        {
            parent = VisualTreeHelper.GetParent(parent);
        }

        return parent as TreeViewItem;
  }
}
theseven7
A: 

This is by far the easiest solution. Just create a rectangle, call it Hb, and set its margine to -100px and not visible. Only set it to Visible when you've it selected or mouse over. It's a hack, but you're good for up to 5 levels of nested TreeViewItems (100 > 19*5)

     <ControlTemplate TargetType="{x:Type TreeViewItem}">
  <Grid>
   <Grid.ColumnDefinitions>
    <ColumnDefinition MinWidth="19" Width="Auto"/>
    <ColumnDefinition Width="*"/>
   </Grid.ColumnDefinitions>
   <Grid.RowDefinitions>
    <RowDefinition Height="Auto"/>
    <RowDefinition/>
   </Grid.RowDefinitions>
                        <ToggleButton x:Name="Expander" Style="{StaticResource ExpandCollapseToggleStyle}" IsChecked="{Binding IsExpanded, RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press" VerticalAlignment="Top" Panel.ZIndex="1"/>
   <Rectangle x:Name="Hb" Width="Auto" Height="Auto" Grid.ColumnSpan="2" Margin="-100,0,0,0" Panel.ZIndex="-1" Visibility="Hidden" />
                        <Border x:Name="Bd" SnapsToDevicePixels="true" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" Grid.Column="1" Panel.ZIndex="0">
    <ContentPresenter x:Name="PART_Header" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" ContentSource="Header" HorizontalAlignment="Stretch"/>
   </Border>
   <ItemsPresenter x:Name="ItemsHost" Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2" Margin="19,0,0,0"/>
  </Grid>
Reza Sanaie
A: 

Used something like theseven7 to facilitate use of bendewey's code with templated TreeViewItems...

    public static int GetDepth(this TreeViewItem item)
    {
        FrameworkElement elem = item;
        var parent = VisualTreeHelper.GetParent(item);
        var count = 0;
        while (parent != null && !(parent is TreeView))
        {
            var tvi = parent as TreeViewItem;
            if (parent is TreeViewItem)
                count++;
            parent = VisualTreeHelper.GetParent(parent);
        }
        return count;
    }
Benjamin