OrgChart for WPF and Silverlight | ComponentOne
C1OrgChart Task-Based Help / Expanding and Collapsing C1OrgChart Nodes
In This Topic
    Expanding and Collapsing C1OrgChart Nodes
    In This Topic

    C1OrgChart allows you to create a collapsible C1OrgChart that behaves similarly to a TreeView control. Complete the following steps to expand and collapse C1OrgChart nodes:

    1. From the Visual Studio File menu select New and choose Project.
    2. In the New Project dialog box choose a language in the left-side menu, choose .NET 6.0 in the Framework drop-down list, and enter OrgChart as a name for the project.
    3. In the Solution Explorer, right-click the project name and choose Add Reference. In the Add Reference dialog box, locate and select the following assemblies and click OK to add references to your project:
      • C1.Silverlight
      • C1.Silverlight.OrgChart
    4. Add the xmlns:c1="http://schemas.componentone.com/winfx/2006/xaml" namespace to your namespace declarations in the <Window> tag. This is a more general namespace that will work with most of the controls in Silverlight Edition.
    5. Add the following namespace to your application's <Window> tag:

       

      xmlns:local="clr-namespace:OrgChart"
          
      
    6. Insert the following XAML markup directly above the <c1:C1OrgChart> </c1:C1OrgChart> tags to create the C1OrgChart data templates:

      XAML
      Copy Code
      <Window.Resources>
              <!-- TemplateSelector: picks _tplDirector or _tlpOther -->
              <local:PersonTemplateSelector x:Key="_personTplSelector">
                  <local:PersonTemplateSelector.DirectorTemplate>
                      <!-- data template for Directors -->
                      <DataTemplate>
                          <Border Background="Gold" BorderBrush="Black" BorderThickness="2 2 4 4" CornerRadius="6" Margin="20" MaxWidth="200">
                              <StackPanel Orientation="Vertical">
                                  <Border CornerRadius="6 6 0 0" Background="Black">
                                      <StackPanel Orientation="Horizontal">
                                          <CheckBox Margin="4 0" IsChecked="{Binding IsCollapsed, Mode=TwoWay, RelativeSource={RelativeSource AncestorType=c1:C1OrgChart}}"/>
                                          <Ellipse Width="12" Height="12" Fill="Gold" Margin="4" />
                                          <TextBlock Text="{Binding Name}" FontWeight="Bold" FontSize="16" Foreground="Gold" />
                                      </StackPanel>
                                  </Border>
                                  <TextBlock Text="{Binding Position}" Padding="6 0" FontSize="14" FontStyle="Italic" HorizontalAlignment="Right" />
                              </StackPanel>
                          </Border>
                      </DataTemplate>
                  </local:PersonTemplateSelector.DirectorTemplate>
                  <local:PersonTemplateSelector.OtherTemplate>
                      <!-- data template for everyone else -->
                      <DataTemplate>
                          <Border Background="WhiteSmoke" BorderBrush="Black" BorderThickness="1 1 2 2" CornerRadius="6" MaxWidth="200">
                              <StackPanel Orientation="Vertical">
                                  <Border CornerRadius="6 6 0 0" Background="Black">
                                      <StackPanel Orientation="Horizontal">
                                          <CheckBox Margin="4 0" IsChecked="{Binding IsCollapsed, Mode=TwoWay, RelativeSource={RelativeSource AncestorType=c1:C1OrgChart}}"/>
                                          <TextBlock Text="{Binding Name}" FontWeight="Bold" FontSize="14" Foreground="WhiteSmoke" Padding="4 0 0 0"></TextBlock>
                                      </StackPanel>
                                  </Border>
                                  <TextBlock Text="{Binding Notes}" Padding="6 0" FontSize="9.5" TextWrapping="Wrap" />
                                  <TextBlock Text="{Binding Position}" Padding="6 0" FontSize="12" FontStyle="Italic" HorizontalAlignment="Right" />
                              </StackPanel>
                          </Border>
                        </DataTemplate>
                  </local:PersonTemplateSelector.OtherTemplate>
              </local:PersonTemplateSelector>
          </Window.Resources>
      
    7. Insert the following markup to create the C1OrgChart control and its control panel. The following XAML will add a ScrollViewer control in addition to the C1OrgChart control:

      XAML
      Copy Code
      <!-- org chart -->
              <ScrollViewer Background="White" Grid.Row="1" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Padding="0">
                  <c1:C1OrgChart x:Name="_orgChart" Grid.Row="1" Orientation="Horizontal" ItemTemplateSelector="{StaticResource _personTplSelector}"
                                 ConnectorStroke="Black" ConnectorThickness="2" IsCollapsed="False">
                      <!-- scale transform bound to slider -->
                      <c1:C1OrgChart.RenderTransform>
                          <ScaleTransform ScaleX="{Binding Value, ElementName=_sliderZoom}" ScaleY="{Binding Value, ElementName=_sliderZoom}" />
                      </c1:C1OrgChart.RenderTransform>
                      <!-- template used to show tree nodes -->
                      <!-- not used in this sample since we are using a template selector -->
                      <!--<c1:C1OrgChart.ItemTemplate />-->
                  </c1:C1OrgChart>
              </ScrollViewer>
      
    8. Add the following XAML markup between the </Window.Resources> and the <c1:C1OrgChart> tags:

      XAML
      Copy Code
      <!-- layout root -->
          <Grid x:Name="LayoutRoot">
              <Grid.RowDefinitions>
                  <RowDefinition Height="Auto" />
                  <RowDefinition />
              </Grid.RowDefinitions>
              <!-- control panel -->
              <StackPanel Orientation="Horizontal" VerticalAlignment="Top" Margin="0 8">
                  <Button Content="New Data" Padding="8 0" Click="Button_Click" />
                  <TextBlock Text="  Zoom: " VerticalAlignment="Center" />
                  <Slider x:Name="_sliderZoom" VerticalAlignment="Center" Minimum=".01" Maximum="1" Value="1" Width="200" />
              </StackPanel>
      
    9. Right-click the page and select View Code from the list. Import the following namespace into the code file:

      Visual Basic
      Copy Code
      Imports C1.Silverlight.OrgChart
      

       

      C#
      Copy Code
      using C1.Silverlight.OrgChart;
      
    10. Insert the following code directly below the InitializeComponent() method:

      Visual Basic
      Copy Code
      CreateData()
          End Sub
          Private Sub Button_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
              CreateData()
          End Sub
          Private Sub CreateData()
              Dim p = Data.Person.CreatePerson(10)
              _orgChart.Header = p
          End Sub
          Public Property DEMO_Orientation As Orientation
              Get
                  Return _orgChart.Orientation
              End Get
              Set(value As Orientation)
                  _orgChart.Orientation = value
              End Set
          End Property
          Public Property DEMO_HorizontalContentAlignment As HorizontalAlignment
              Get
                  Return _orgChart.HorizontalContentAlignment
              End Get
              Set(value As HorizontalAlignment)
                  _orgChart.HorizontalContentAlignment = value
              End Set
          End Property
       
          Public Property DEMO_VerticalContentAlignment As VerticalAlignment
              Get
                  Return _orgChart.VerticalContentAlignment
              End Get
              Set(value As VerticalAlignment)
                  _orgChart.VerticalContentAlignment = value
              End Set
          End Property
      End Class
      

       

      C#
      Copy Code
      CreateData();
              }
              void Button_Click(object sender, RoutedEventArgs e)
              {
                  CreateData();
              }
              void CreateData()
              {
                  var p = Data.Person.CreatePerson(10);
                  _orgChart.Header = p;
              }
              public Orientation DEMO_Orientation
              {
                  get
                  {
                      return _orgChart.Orientation;
                  }
                  set
                  {
                      _orgChart.Orientation = value;
                  }
              }      
              public HorizontalAlignment DEMO_HorizontalContentAlignment
              {
                  get
                  {
                      return _orgChart.HorizontalContentAlignment;
                  }
                  set
                  {
                      _orgChart.HorizontalContentAlignment = value;
                  }
              }
              public VerticalAlignment DEMO_VerticalContentAlignment
              {
                  get
                  {
                      return _orgChart.VerticalContentAlignment;
                  }
                  set
                  {
                      _orgChart.VerticalContentAlignment = value;
                  }
              }
          }
      
    11. Add the following code to select the templates for items being created:

      Visual Basic
      Copy Code
      'Class used to select the templates for items being created.
      Public Class PersonTemplateSelector
          Inherits DataTemplateSelector
          Public Overrides Function SelectTemplate(item As Object, container As DependencyObject) As DataTemplate
              Dim p = TryCast(item, Data.Person)
              'var e = Application.Current.RootVisual as FrameworkElement;
              'return p.Position.IndexOf("Director") > -1
              '    ? e.Resources["_tplDirector"] as DataTemplate
              '    : e.Resources["_tplOther"] as DataTemplate;
              Return If(p.Position.IndexOf("Director") > -1, DirectorTemplate, OtherTemplate)
          End Function
          ' collapse the chart to a given level
          Private Sub CollapseExpand(node As C1.WPF.OrgChart.C1OrgChart, level As Integer, maxLevel As Integer)
              If level >= maxLevel Then
                  node.IsCollapsed = True
              Else
                  node.IsCollapsed = False
                  For Each subNode In node.ChildNodes
                      CollapseExpand(subNode, level + 1, maxLevel)
                  Next
              End If
          End Sub
          Public Property DirectorTemplate() As DataTemplate
              Get
                  Return m_DirectorTemplate
              End Get
              Set(value As DataTemplate)
                  m_DirectorTemplate = Value
              End Set
          End Property
          Private m_DirectorTemplate As DataTemplate
          Public Property OtherTemplate() As DataTemplate
              Get
                  Return m_OtherTemplate
              End Get
              Set(value As DataTemplate)
                  m_OtherTemplate = Value
              End Set
          End Property
          Private m_OtherTemplate As DataTemplate
      End Class
      

       

      C#
      Copy Code
      /// Class used to select the templates for items being created.
          /// </summary>
          public class PersonTemplateSelector : DataTemplateSelector
          {
              public override DataTemplate SelectTemplate(object item, DependencyObject container)
              {
                  var p = item as Data.Person;
                  //var e = Application.Current.RootVisual as FrameworkElement;
                  //return p.Position.IndexOf("Director") > -1
                  //    ? e.Resources["_tplDirector"] as DataTemplate
                  //    : e.Resources["_tplOther"] as DataTemplate;
                  return p.Position.IndexOf("Director") > -1
                      ? DirectorTemplate
                      : OtherTemplate;
              }
              // collapse the chart to a given level
              void CollapseExpand(C1OrgChart node, int level, int maxLevel)
              {
                  if (level >= maxLevel)
                  {
                      node.IsCollapsed = true;
                  }
                  else
                  {
                      node.IsCollapsed = false;
                      foreach (var subNode in node.ChildNodes)
                      {
                          CollapseExpand(subNode, level + 1, maxLevel);
                      }
                  }
              }
              public DataTemplate DirectorTemplate { get; set; }
              public DataTemplate OtherTemplate { get; set; }
          }
      }
      
    12. Locate your application name in the Solution Explorer. Right-click on the name and select Add | New Item from the list. Select Code File from the template window and name the code file Person.cs or Person.vb.
    13. Add the following namespaces to the Person code file:

      Visual Basic
      Copy Code
      Imports System
      Imports System.Collections
      Imports System.Collections.Generic
      Imports System.Collections.ObjectModel
      
      C#
      Copy Code
      using System;
      using System.Collections;
      using System.Collections.Generic;
      using System.Collections.ObjectModel;
      
    14. Insert the following code below the namespaces to create the hierarchical data items which will be called to create the data in the C1OrgChart:

      Visual Basic
      Copy Code
      'Class used to select the templates for items being created.
      Public Class PersonTemplateSelector
          Inherits DataTemplateSelector
          Public Overrides Function SelectTemplate(item As Object, container As DependencyObject) As DataTemplate
              Dim p = TryCast(item, Data.Person)
              'var e = Application.Current.RootVisual as FrameworkElement;
              'return p.Position.IndexOf("Director") > -1
              '    ? e.Resources["_tplDirector"] as DataTemplate
              '    : e.Resources["_tplOther"] as DataTemplate;
              Return If(p.Position.IndexOf("Director") > -1, DirectorTemplate, OtherTemplate)
          End Function
          ' collapse the chart to a given level
          Private Sub CollapseExpand(node As C1.WPF.OrgChart.C1OrgChart, level As Integer, maxLevel As Integer)
              If level >= maxLevel Then
                  node.IsCollapsed = True
              Else
                  node.IsCollapsed = False
                  For Each subNode In node.ChildNodes
                      CollapseExpand(subNode, level + 1, maxLevel)
                  Next
              End If
          End Sub
          Public Property DirectorTemplate() As DataTemplate
              Get
                  Return m_DirectorTemplate
              End Get
              Set(value As DataTemplate)
                  m_DirectorTemplate = Value
              End Set
          End Property
          Private m_DirectorTemplate As DataTemplate
          Public Property OtherTemplate() As DataTemplate
              Get
                  Return m_OtherTemplate
              End Get
              Set(value As DataTemplate)
                  m_OtherTemplate = Value
              End Set
          End Property
          Private m_OtherTemplate As DataTemplate
      End Class
      
      C#
      Copy Code
      namespace Data
      {
          /// <summary>
          /// Our hierarchical data item: A Person has Subordinates of type Person.
          /// </summary>
          public class Person
          {
              ObservableCollection<Person> _list = new ObservableCollection<Person>();
              #region ** object model
              public string Name { get; set; }
              public string Position { get; set; }
              public string Notes { get; set; }
              public IList<Person> Subordinates
              {
                  get { return _list; }
              }
              public int TotalCount
              {
                  get
                  {
                      var count = 1;
                      foreach (var p in Subordinates)
                      {
                          count += p.TotalCount;
                      }
                      return count;
                  }
              }
              public override string ToString()
              {
                  return string.Format("{0}:\r\n\t{1}", Name, Position);
              }
              #endregion
              #region ** Person factory
              static Random _rnd = new Random();
              static string[] _positions = "Director|Manager|Designer|Developer|Writer|Assistant".Split('|');
              static string[] _areas = "Development|Marketing|Sales|Support|Accounting".Split('|');
              static string[] _first = "John|Paul|Dan|Dave|Rich|Mark|Greg|Erin|Susan|Sarah|Tim|Trevor|Kevin|Mark|Dewey|Huey|Larry|Moe|Curly|Adam|Albert".Split('|');
              static string[] _last = "Smith|Doe|Williams|Sorensen|Hansen|Mandela|Johnson|Ward|Woodman|Jordan|Mays|Kevorkian|Trudeau|Hendrix|Clinton".Split('|');
              static string[] _verb = "likes|reads|studies|hates|exercises|dreams|plays|writes|argues|sleeps|ignores".Split('|');
              static string[] _adjective = "long|short|important|pompous|hard|complex|advanced|modern|boring|strange|curious|obsolete|bizarre".Split('|');
              static string[] _noun = "products|tasks|goals|campaigns|books|computers|people|meetings|food|jokes|accomplishments|screens|pages".Split('|');
              public static Person CreatePerson(int level)
              {
                  var p = CreatePerson();
                  if (level > 0)
                  {
                      level--;
                      for (int i = 0; i < _rnd.Next(1, 4); i++)
                      {
                          p.Subordinates.Add(CreatePerson(_rnd.Next(level / 2, level)));
                      }
                  }
                  return p;
              }
              public static Person CreatePerson()
              {
                  var p = new Person();
                  p.Position = string.Format("{0} of {1}", GetItem(_positions), GetItem(_areas));
                  p.Name = string.Format("{0} {1}", GetItem(_first), GetItem(_last));
                  p.Notes = string.Format("{0} {1} {2} {3}", p.Name, GetItem(_verb), GetItem(_adjective), GetItem(_noun));
                  while (_rnd.NextDouble() < .5)
                  {
                      p.Notes += string.Format(" and {0} {1} {2}", GetItem(_verb), GetItem(_adjective), GetItem(_noun));
                  }
                  p.Notes += ".";
                  return p;
              }
              static string GetItem(string[] list)
              {
                  return list[_rnd.Next(0, list.Length)];
              }
              #endregion
          }
      }
      
    15. Press F5 to run your application. The C1OrgChart should resemble the following image:

      C1OrgChart for WPF

    16. Click the CheckBox in the corner of one of the Main Item nodes. Note how the C1OrgChart collapses:

      C1OrgChart for WPF