views:

2080

answers:

7

How can I expand the whole TreeView in Silverlight?

EDIT: Here is the XAML :

<controls:TreeView x:Name="tv">
    <controls:TreeView.ItemTemplate>
        <common:HierarchicalDataTemplate ItemsSource="{Binding Children}">
            <CheckBox IsChecked="{Binding Visible, Mode=TwoWay}" Content="{Binding Name}"/>
        </common:HierarchicalDataTemplate>
    </controls:TreeView.ItemTemplate>
</controls:TreeView>

Perhaps using the ItemTemplate makes the ItemContainerGenerator.ContainerFromIndex return null on any index?

A: 

yourtreeview.ExpandAll()

EDIT: Martin indicated that the ExpandAll() method does not exist for TreeView, however, I just typed the following code in my Silverlight Project and intellisense picked up:

TreeView test = new TreeView();
            test.ExpandAll();

You can also set the TreeView attribute IsExpanded = "true" in the XAML although I am not sure if that expands the whole tree or just one level

Johannes
`ExpandAll` is not a method on `TreeView` in Silverlight.
Martin Liversage
I'm refering to the Silverlight 3 control `System.Windows.Controls.TreeView` in the `System.Windows.Controls` assembly. This class does not have an `ExpandAll` method. After a bit more investigation I discovered that the Silverlight Toolkit has an `ExpandAll` extension method, and it is probably that method itellisense is picking up.
Martin Liversage
Expand all is an extension method but it doesn't do anything so it doesn't help. Sorry :(
Andrei Rinea
+3  A: 

You will have to use TreeView.ItemContainerGenerator to get the TreeViewItem instances and set IsExpanded on those. This is slightly complex as the expansion is performed asynchronously. You can find code samples on the internet or simply use this extension method:

public static class TreeViewExtensions {

  public static void ExpandAll(this TreeView treeView) {
    for (Int32 i = 0; i < treeView.Items.Count; ++i) {
      TreeViewItem item = treeView.ItemContainerGenerator.ContainerFromIndex(i) as TreeViewItem;
      if (item != null)
        ExpandAll(item);
    }
  }

  static void ExpandAll(TreeViewItem item) {
    if (!item.IsExpanded) {
      item.IsExpanded = true;
      item.Dispatcher.BeginInvoke(() => ExpandAll(item));
    }
    else {
      for (Int32 i = 0; i < item.Items.Count; ++i) {
        TreeViewItem childItem = item.ItemContainerGenerator.ContainerFromIndex(i) as TreeViewItem;
        if (childItem != null)
          ExpandAll(childItem);
      }
    }
  }
Martin Liversage
I guess it should work (the sample).
Andrei Rinea
I keep getting null on TreeView.ItemContainerGenerator.ContainerFromIndex on all indices.. don't get it why..
Andrei Rinea
A: 

I do not see, that the question is answered, since the TreeViewItem is always NULL:

TreeViewItem item = treeView.ItemContainerGenerator.ContainerFromIndex(i) as TreeViewItem;
      if (item != null)
        ExpandAll(item);

Call UpdateLayout() on the TreeView before you try to get the TreeViewItem. That should help!

Sven Sönnichsen
If the `TreeView` hasn't been loaded you cannot use `ExpandAll` so I guess you are calling the method too early. Add a handler for the `TreeView.Loaded` event and call `ExpandAll` there. Another option is of course to call `UpdateLayout`, but I prefer the other approach.
Martin Liversage
+2  A: 

First, read this post: http://bea.stollnitz.com/blog/?p=55

Second, inherit TreeViewItem and TreeView:

public class TreeViewItemEx : TreeViewItem {
 protected override DependencyObject GetContainerForItemOverride() {
  TreeViewItemEx tvi = new TreeViewItemEx();
  Binding expandedBinding = new Binding("IsExpanded");
  expandedBinding.Mode = BindingMode.TwoWay;
  tvi.SetBinding(TreeViewItemEx.IsExpandedProperty, expandedBinding);
  return tvi;
 }
}

public class TreeViewEx : TreeView {
 protected override DependencyObject GetContainerForItemOverride() {
  TreeViewItemEx tvi = new TreeViewItemEx();
  Binding expandedBinding = new Binding("IsExpanded");
  expandedBinding.Mode = BindingMode.TwoWay;
  tvi.SetBinding(TreeViewItemEx.IsExpandedProperty, expandedBinding);

  return tvi;
 }
}

Third, binding your Model's property to "IsExpanded".

Homer
A: 

if you wish to do in in Xaml, it can be done using silverlight toolkit theming assembly & setting styles resource. Code is available here: http://bea.stollnitz.com/blog/?p=54

Mev
A: 

TreeViewMenu.Dispatcher.BeginInvoke(() => TreeViewMenu.ExpandAll());

Just add this line after creating the treeview items. thats all!

Susanta
+2  A: 

I know ths is a bit late but I found this when looking for an answer and have since found that in SL4 you can use implicit theming to do this:

         <Style TargetType="controls:TreeViewItem">
                    <Setter Property="IsExpanded"
                            Value="True" />
          </Style>
Mark