Click here to Skip to main content
15,891,473 members
Articles / Desktop Programming / WPF

Tuning Up The TreeView - Part 2

Rate me:
Please Sign up or sign in to vote.
4.75/5 (7 votes)
2 Mar 2010CPOL11 min read 41.9K   1.6K   40  
Improved TreeView sorting, filtering, selection, and efficiency.
<Window x:Class="DirectoryTree.VM.Main"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
        xmlns:appvm="clr-namespace:DirectoryTree.VM"
        Title="Directory Tree Prototype - Hierarchical Binding"
        Height="500" Width="550" >

<!-- History: 2/2010 - Lee Robie - robiesw@cinci.rr.com -->  
<Grid>
   <Grid.RowDefinitions>
      <RowDefinition Height="33" />       <!-- Action Buttons-->
      <RowDefinition Height="2"  />
      <RowDefinition Height="*"  />       <!-- Tree Contents -->
   </Grid.RowDefinitions>

   <StackPanel Orientation="Horizontal" Grid.Row="0" Grid.Column="0" >
      <StackPanel.Resources>
         <Style TargetType="{x:Type Label}">
            <Setter Property="FontSize"            Value="12" />
            <Setter Property="Padding"             Value="0, 2, 0, 2" />
            <Setter Property="Margin"              Value="3, 6, 0, 1" />
         </Style>
         
         <Style TargetType="{x:Type Button}">
            <Setter Property="VerticalAlignment"   Value="Top" />
            <Setter Property="Width"               Value="70" />
            <Setter Property="Padding"             Value="2, 1" />
            <Setter Property="Margin"              Value="2, 4, 10, 2" />
         </Style>
        
      </StackPanel.Resources>

      <Button Name="btnSort"    Content="Sort by Name" Width="80"
              Margin="20, 4, 10, 2" />
      <Button Name="btnFilter"  Content="Filter: None" Width="80"
              Margin="2, 4, 10, 2" />
      
      <Label Content="CRUD:"  Margin="20,6,10,2"  />

      <Button Name="btnAdd"      Content="_Add Dir"       ToolTip="C-Create" />
      <Button Name="btnDump"     Content="_Dump"          ToolTip="R-Read"   />
      <Button Name="btnRename"   Content="_Rename Dir"    ToolTip="U-Update" />
      <Button Name="btnDelete"   Content="_Delete Dir"    ToolTip="D-Delete" />

   </StackPanel>
   
   <Rectangle Grid.Row="1" Grid.ColumnSpan="2" Height="1" Fill="LightGray" />
  
   <TreeView Name="tvDirTree"
             ItemsSource="{Binding Path=Drives}"
             Grid.Row="2"
             BorderThickness="0" >

      <TreeView.Resources>
         
         <ContextMenu x:Key="DriveMenu">
            <MenuItem Header="Refresh" Click="DoRefreshDrive" />
         </ContextMenu>

         <Style x:Key="TreeText" TargetType="{x:Type TextBlock}" >
            <Setter Property="Foreground" Value="Black" />
            <Style.Triggers>
               <DataTrigger Binding="{Binding Path=Temperature}" 
                            Value="{x:Static appvm:DirTemp.Invalid}" >
                  <Setter Property="Foreground" Value="Lightgray" />
               </DataTrigger>
            </Style.Triggers>
         </Style>
         
         <!-- Following style needed to avoid binding error during sort -->
         <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="HorizontalContentAlignment" Value="Left" />
            <Setter Property="VerticalContentAlignment" Value="Center" />
         </Style>
         
         <HierarchicalDataTemplate DataType="{x:Type appvm:Drive}" 
                                   ItemsSource="{Binding Path=ChildrenView}" >
             <StackPanel Orientation="Horizontal">
               <Image Width="14" Height="14" 
                      Source="{StaticResource imgHardDisk}" />
               <TextBlock Text="{Binding Path=Name}" />
            </StackPanel>
         </HierarchicalDataTemplate>
         
         <Style x:Key="FolderImage" TargetType="{x:Type Image}" >
            <Setter Property="Source" Value="{StaticResource imgFolder}" />
            <Style.Triggers>
               <DataTrigger Binding="{Binding Path=Temperature}" 
                            Value="{x:Static appvm:DirTemp.Invalid}" >
                  <Setter Property="Source" Value="{StaticResource imgFolderInvalid}" />
               </DataTrigger>
               <DataTrigger Binding="{Binding Path=Temperature}" 
                            Value="{x:Static appvm:DirTemp.Empty}" >
                  <Setter Property="Source" Value="{StaticResource imgFolderEmpty}" />
               </DataTrigger>
               <DataTrigger Binding="{Binding Path=Temperature}" 
                            Value="{x:Static appvm:DirTemp.Cold}" >
                  <Setter Property="Source" Value="{StaticResource imgFolderCold}" />
               </DataTrigger>
               <DataTrigger Binding="{Binding Path=Temperature}" 
                            Value="{x:Static appvm:DirTemp.Hot}" >
                  <Setter Property="Source" Value="{StaticResource imgFolderHot}" />
               </DataTrigger>
            </Style.Triggers>
         </Style>

         <HierarchicalDataTemplate DataType="{x:Type appvm:Directory}" 
                                   ItemsSource="{Binding Path=ChildrenView}" >
             <StackPanel Orientation="Horizontal" >
                <Image Style="{StaticResource FolderImage}"
                       Width="14" Height="14" 
                       Margin="0, 0, 4, 0" />
                <TextBlock Text="{Binding Path=Name}"
                           Style="{StaticResource TreeText}" />
             </StackPanel>
         </HierarchicalDataTemplate>
         
      </TreeView.Resources>

      <TreeView.ItemContainerStyle>
         <!-- This Style binds a WPF TreeViewItem to a TreeNode.  -->
         <Style TargetType="{x:Type TreeViewItem}">
            <EventSetter Event="TreeViewItem.MouseRightButtonDown"  
                         Handler="DoMouseRtButton" />
            <EventSetter Event="TreeViewItem.ContextMenuOpening"  
                         Handler="DoContextMenuOpening" />
            <Setter Property="ContextMenu" 
                    Value="{Binding Source={StaticResource DriveMenu}}"/>
            
            <Setter Property="IsExpanded" Value="{Binding Path=IsExpanded, Mode=TwoWay}" />
            <Setter Property="FontWeight" Value="Normal" />

            <!-- Following styles needed to avoid binding error during sort -->
            <Setter Property="HorizontalContentAlignment" Value="Left" />
            <Setter Property="VerticalContentAlignment" Value="Center" />

            <Style.Triggers>
               <Trigger Property="IsSelected" Value="True">
                  <Setter Property="FontWeight" Value="Bold" />
               </Trigger>
            </Style.Triggers>
        </Style>
      </TreeView.ItemContainerStyle>
   </TreeView>
   
</Grid>
</Window>

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
Lee has worked on user interfaces, graphics, computational geometry, memory management, threading, and assorted applications in C#, Java, C++, and C. He started out programming in Fortran on a 128 Kb PDP/11, which only proves that he's old, not smart. Lee also writes about chronic illness and his love of animals; his auto racing related articles are here.

Comments and Discussions