יום ראשון, 3 באפריל 2011

Find String in WPF TreeView control


How to find string in TreeView control?
The biggest thing about WPF is data binding and so in WPF TreeView very important to what source you binded your TreeView.
For example my source will 3 hierarchical classes A, B and C:

public class A
{
   public string Filed {get; set;}
   List<B> bList = new List<B>();
}

public class B
{
   public string Filed {get; set;}
   List<C> bList = new List<C>();
}

public class C
{
   public string Filed {get; set;}
}


public void Main()
{
   A a = new A();
   B b = new B();
B bb = new B();
C c = new C();
C cc = new C();
C ccc = new C();
a.bList.Add(b);
a.bList.Add(bb);
b.cList.Add(c);
b.cList.Add(cc);
b.cList.Add(ccc);
}


And in XAML we created HierarchicalDataView with relevant DataBinding and got TreeView:

<HierarchicalDataTemplate x:Key="elementTemplate">   
 <StackPanel Orientation="Horizontal">
  <TextBlock Text="{Binding cList}"/>
    <TextBlock Text="{Binding NormaTimeCount, StringFormat= - כמות: {0}}"/>
 </StackPanel>
 </HierarchicalDataTemplate>
 <HierarchicalDataTemplate x:Key="chapterTemplate" 
   ItemsSource="{Binding Path=bList}"                   
   ItemTemplate="{StaticResource elementTemplate}">
   <Grid>
    <Grid.RowDefinitions>
    <RowDefinition></RowDefinition>
    <RowDefinition></RowDefinition>
    </Grid.RowDefinitions>
   <Grid.ColumnDefinitions>
    <ColumnDefinition></ColumnDefinition>
    <ColumnDefinition></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <TextBlock Text="{Binding ld_name}" Grid.Column="0" Grid.Row="0" />
   </Grid>
 </HierarchicalDataTemplate>
 <HierarchicalDataTemplate x:Key="ClassificationTemplate"                            ItemsSource="{Binding Path=Chapters.List}"                   
   ItemTemplate="{StaticResource chapterTemplate}">
   <Grid>
    <Grid.RowDefinitions>
    <RowDefinition></RowDefinition>
    <RowDefinition></RowDefinition>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
    <ColumnDefinition></ColumnDefinition>
    <ColumnDefinition></ColumnDefinition>
    <ColumnDefinition></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <TextBlock Text="{Binding ld_name}" Grid.Column="0" Grid.Row="0" />
  </Grid>
  </HierarchicalDataTemplate>

C# code:

private void btnFind_Click(object sender, RoutedEventArgs e)
{
   Find(_MainTreeView, textToFindt);
}

private void Find(TreeView mainTreeView, string findToText)
{
   foreach (object item in mainTreeView.Items)
   {
     TreeViewItem treeItem = mainTreeView.ItemContainerGenerator.ContainerFromItem(item) 
                                                                          as TreeViewItem;
                if (treeItem != null)
                    FindAll(treeItem, findText);
                if (item != null)
                {
                    dynamic obje = treeItem.Header;
                    if (isContains(obje.ld_name, findText))
                    {
                        treeItem.Focus();
                        treeItem.IsExpanded = true;
                        treeItem.Background = Brushes.Red;
                    }
                }
            }
        }
 
void FindAll(ItemsControl items, string textToFind)
        {
            foreach (object obj in items.Items)
            {
                ItemsControl childControl = items.ItemContainerGenerator.ContainerFromItem(obj) as ItemsControl;
                if (childControl != null)
                {
                    FindAll(childControl, findText); // Recursion
                }
                TreeViewItem item = childControl as TreeViewItem;
                if (item != null)
                {
                     //only if you dont know type of your Tree (in our case it's A, B or C and you need to use if or switch                        - case statement)
                    dynamic obje = item.Header;                     if (isContains(obje.ld_name, findText))                     {                         item.Focus();                         item.IsExpanded = true; // if you need to expand and show it                         item.Background = Brushes.Red;                     }                 }             }         }

תגובה 1: