ComponentOne OrgChart for UWP
OrgChart for UWP 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. 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:
    Markup
    Copy Code
     <!-- org chart -->
            <ScrollViewer Grid.Row="2" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
                <orgchart:C1OrgChart
        x:Name="_orgChart"              
        Grid.Row="1"
        Orientation="Vertical"
        HorizontalAlignment="Center" VerticalAlignment="Center"
        ConnectorStroke="OrangeRed" ConnectorThickness="{Binding Path=Subordinates.Count}" 
                         Foreground="#FF39B925" Xaml:C1NagScreen.Nag="True" >
                    <!-- scale transform bound to slider -->
                    <orgchart:C1OrgChart.RenderTransform>
                        <ScaleTransform
          ScaleX="{Binding Value, ElementName=_sliderZoom}"
          ScaleY="{Binding Value, ElementName=_sliderZoom}" />
                    </orgchart:C1OrgChart.RenderTransform>
                    <!-- template used to show tree nodes -->
                    <orgchart:C1OrgChart.ItemTemplate>
                        <DataTemplate>
                            <!-- outer border -->
                            <Border
           Background="WhiteSmoke" BorderBrush="Black"
           BorderThickness="1 1 2 2" CornerRadius="6"
           MaxWidth="200" >
                                <StackPanel Orientation="Vertical" >
                                    <!-- item header -->
                                    <Border CornerRadius="6 6 0 0" Background="Black" >
                                        <StackPanel Orientation="Horizontal">
                                          <!-- bind CheckBox to containing C1OrgChart's IsCollapsed property -->
                                          <CheckBox Margin="4 0" Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked"/>
                                          <!-- item header: person's Name -->
                                          <TextBlock Text="{Binding Name}" FontWeight="Bold" FontSize="14" 
                                           Foreground="WhiteSmoke" Padding="4 0 0 0" />
                                        </StackPanel>
                                    </Border>
                                    <!-- body: person's details -->
                                    <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>
                    </orgchart:C1OrgChart.ItemTemplate>
                </orgchart:C1OrgChart>
            </ScrollViewer>
    
    1. Add the following XAML markup below the <Grid> tag and before the <Scrollviewer> tag. This will add some Grid row definitions, a title for your application, and a control panel that contains the buttons and sliders. This way you can control the zoom, orientation, and data for your C1OrgChart:
    Markup
    Copy Code
    <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition />
            </Grid.RowDefinitions>
            <!-- sample title -->
            <StackPanel Orientation="Horizontal" >
                <TextBlock Text="C1OrgChart: Collapse/Expand Sample" FontSize="16" VerticalAlignment="Bottom" 
                 Foreground="Black" />
                <TextBlock x:Name="_tbTotal" VerticalAlignment="Bottom" />
            </StackPanel>
            <!-- control panel -->
            <StackPanel Orientation="Horizontal" VerticalAlignment="Top" Grid.Row="1">
                <Button Content="Refresh Data" Padding="8 0" Click="Button_Refresh_Click" 
                 Foreground="Black" BorderBrush="Black" />
                <TextBlock Text=" Zoom: " VerticalAlignment="Center" />
                <Slider x:Name="_sliderZoom" Minimum=".01" Maximum="1" Value="1" Width="100" SmallChange="0.01" 
                 StepFrequency="0.01" Height="44" HorizontalAlignment="Left" Foreground="#FFFF1B1B" Background="#29C91515"
                 VerticalAlignment="Center" />
                <CheckBox Margin="20 0" Content="Horizontal" Click="CheckBox_Click" Background="#FF0Cffff" Foreground="Black" />
                <Button Content="Collapse to Level 3" Padding="8 0" Click="Button_Collapse_Click" Foreground="Black" 
                 BorderBrush="Black" />
            </StackPanel>
    
    1. 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.Xaml.OrgChart
    

    C#
    Copy Code
    using C1.Xaml.OrgChart
    
    1. Insert the following code directly below the InitializeComponent() method:
    Visual Basic
    Copy Code
    CreateData()
    

    C#
    Copy Code
    CreateData();
    
    1. Add the following code to handle the button click and checkbox click events, and to handle the C1OrgChart toggling:
    Visual Basic
    Copy Code
    Private Sub CheckBox_Click(sender As Object, e As RoutedEventArgs)
            _orgChart.Orientation = If(DirectCast(sender, CheckBox).IsChecked.Value, 
            Orientation.Horizontal, Orientation.Vertical)
        End Sub
        ' rebuild the chart using new random data
        Private Sub Button_Refresh_Click(sender As Object, e As RoutedEventArgs)
            CreateData()
        End Sub
        ' collapse the chart to level 3
        Private Sub Button_Collapse_Click(sender As Object, e As RoutedEventArgs)
            ToggleCollapseExpand(_orgChart, 0, 3)
        End Sub
        ' collapse the chart to a given level
        Private Sub ToggleCollapseExpand(node As C1OrgChart, level As Integer, maxLevel As Integer)
            If level >= maxLevel Then
                node.IsCollapsed = True
            Else
                node.IsCollapsed = False
                For Each subNode In node.ChildNodes
                    ToggleCollapseExpand(subNode, level + 1, maxLevel)
                Next
            End If
        End Sub
    

    C#
    Copy Code
    void CheckBox_Click(object sender, RoutedEventArgs e)
            {
                _orgChart.Orientation = ((CheckBox)sender).IsChecked.Value
                    ? Orientation.Horizontal
                    : Orientation.Vertical;
            }
            // rebuild the chart using new random data
            void Button_Refresh_Click(object sender, RoutedEventArgs e)
            {
                CreateData();
            }
            // collapse the chart to level 3
            void Button_Collapse_Click(object sender, RoutedEventArgs e)
            {
                ToggleCollapseExpand(_orgChart, 0, 3);
            }
            // collapse the chart to a given level
            void ToggleCollapseExpand(C1OrgChart node, int level, int maxLevel)
            {
                if (level >= maxLevel)
                {
                    node.IsCollapsed = true;
                }
                else
                {
                    node.IsCollapsed = false;
                    foreach (var subNode in node.ChildNodes)
                    {
                        ToggleCollapseExpand(subNode, level + 1, maxLevel);
                    }
                }
            }
    
    1. Add the following code to create new random data and handle the checkbox events that will allow the C1OrgChart to expand and collapse:
    Visual Basic
    Copy Code
    ' create some random data and assign it to the chart
        Private Sub CreateData()
            Dim p = Person.CreatePerson(15)
            _tbTotal.Text = String.Format(" ({0} items total)", p.TotalCount)
            _orgChart.Header = p
        End Sub
        ' add for supporting expand/collapse in OrgChart sample
        Private Sub CheckBox_Unchecked(sender As Object, e As RoutedEventArgs)
            CheckedChanged(sender)
        End Sub
        Private Sub CheckBox_Checked(sender As Object, e As RoutedEventArgs)
            CheckedChanged(sender)
        End Sub
        Private Sub CheckedChanged(sender As Object)
            Dim checkBox As CheckBox = TryCast(sender, CheckBox)
            Dim parent As FrameworkElement = TryCast(VisualTreeHelper.GetParent(checkBox), FrameworkElement)
            While parent IsNot Nothing AndAlso Not (TypeOf parent Is C1OrgChart)
                parent = TryCast(VisualTreeHelper.GetParent(parent), FrameworkElement)
            End While
            If parent IsNot Nothing Then
                Dim orgChart As C1OrgChart = TryCast(parent, C1OrgChart)
                If checkBox.IsChecked IsNot Nothing Then
                    orgChart.IsCollapsed = checkBox.IsChecked.Value
                End If
            End If
        End Sub
    

    C#
    Copy Code
    // create some random data and assign it to the chart
            void CreateData()
            {
                var p = Person.CreatePerson(15);
                _tbTotal.Text = string.Format(" ({0} items total)", p.TotalCount);
                _orgChart.Header = p;
            }
            // add for supporting expand/collapse in OrgChart sample
            private void CheckBox_Unchecked(object sender, RoutedEventArgs e)
            {
                CheckedChanged(sender);
            }
    private void CheckBox_Checked(object sender, RoutedEventArgs e)
            {
                CheckedChanged(sender);
            }
            private void CheckedChanged(object sender)
            {
                CheckBox checkBox = sender as CheckBox;
                FrameworkElement parent = VisualTreeHelper.GetParent(checkBox) as FrameworkElement;
                while (parent != null && !(parent is C1OrgChart))
                {
                    parent = VisualTreeHelper.GetParent(parent) as FrameworkElement;
                }
                if (parent != null)
                {
                    C1OrgChart orgChart = parent as C1OrgChart;
                    if (checkBox.IsChecked != null)
                    {
                        orgChart.IsCollapsed = checkBox.IsChecked.Value;
                    }
                }
            }
        }
    }
    
    1. 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.
    1. 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;
    

     

    1. 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
    Namespace Data
         ''' <summary>
         ''' Our hierarchical data item: A Person has Subordinates of type Person.
         ''' </summary>
         Public Class Person
             Private _list As New ObservableCollection(Of Person)()
    #Region "** object model"
            Public Property Name() As String
                 Get
                     Return m_Name
                 End Get
                 Set(value As String)
                     m_Name = Value
                 End Set
             End Property
             Private m_Name As String
             Public Property Position() As String
                 Get
                     Return m_Position
                 End Get
                 Set(value As String)
                     m_Position = Value
                 End Set
             End Property
             Private m_Position As String
             Public Property Notes() As String
                 Get
                     Return m_Notes
                 End Get
                 Set(value As String)
                     m_Notes = Value
                 End Set
             End Property
             Private m_Notes As String
             Public ReadOnly Property Subordinates() As IList(Of Person)
                 Get
                     Return _list
                 End Get
             End Property
             Public ReadOnly Property TotalCount() As Integer
                 Get
                     Dim count = 1
                     For Each p In Subordinates
                         count += p.TotalCount
                     Next
                     Return count
                 End Get
             End Property
             Public Overrides Function ToString() As String
                 Return String.Format("{0}:" & vbCr & vbLf & vbTab & "{1}", Name, Position)
             End Function
    #End Region
    #Region "** Person factory"
            Shared _rnd As New Random()
             Shared _positions As String() = "Director|Manager|Designer|Developer|Writer|Assistant".Split("|"c)
             Shared _areas As String() = "Development|Marketing|Sales|Support|Accounting".Split("|"c)
             Shared _first As String() = "John|Paul|Dan|Dave|Rich|Mark|Greg|Erin|Susan|Sarah|Tim|Trevor|Kevin|Mark|Dewey|Huey|Larry|Moe|Curly|Adam|Albert".Split("|"c)
            Shared _last As String() = "Smith|Doe|Williams|Sorensen|Hansen|Mandela|Johnson|Ward|Woodman|Jordan|Mays|Kevorkian|Trudeau|Hendrix|Clinton".Split("|"c)
             Shared _verb As String() = "likes|reads|studies|hates|exercises|dreams|plays|writes|argues|sleeps|ignores".Split("|"c)
             Shared _adjective As String() = "long|short|important|pompous|hard|complex|advanced|modern|boring|strange|curious|obsolete|bizarre".Split("|"c)
             Shared _noun As String() = "products|tasks|goals|campaigns|books|computers|people|meetings|food|jokes|accomplishments|screens|pages".Split("|"c)
            Public Shared Function CreatePerson(level As Integer) As Person
                 Dim p = CreatePerson()
                 If level > 0 Then
                     level -= 1
                     For i As Integer = 0 To _rnd.[Next](1, 4) - 1
                         p.Subordinates.Add(CreatePerson(_rnd.[Next](level \ 2, level)))
                     Next
                 End If
                 Return p
             End Function
             Public Shared Function CreatePerson() As Person
                 Dim 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() < 0.5
                     p.Notes += String.Format(" and {0} {1} {2}", GetItem(_verb), GetItem(_adjective), GetItem(_noun))
                 End While
                p.Notes += "."
                 Return p
             End Function
             Private Shared Function GetItem(list As String()) As String
                 Return list(_rnd.[Next](0, list.Length))
             End Function
    #End Region
         End Class
     End Namespace
    

    C#
    Copy Code
    namespace CollapseExpand
     {
         /// <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
         }
     }
    
    1. Press F5 to run your application. The C1OrgChart should resemble the following image:

     

     

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

     

    See Also