[]
        
(Showing Draft Content)

Expanding and Collapsing C1OrgChart Nodes

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:

    <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:

    <!-- 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:

    <!-- 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:

    Imports C1.Silverlight.OrgChart
    using C1.Silverlight.OrgChart;
  10. Insert the following code directly below the InitializeComponent() method:

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
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;
            }
        }
    }
  1. Add the following code to select the templates for items being created:

'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
/// Class used to select the templates for items being created.
    /// <p>DOC-SUMMARY-TAG-CLOSE</p>
    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; }
    }
}
  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.

  2. Add the following namespaces to the Person code file:

Imports System
Imports System.Collections
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
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:

'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
namespace Data
{
    /// <p>DOC-SUMMARY-TAG-OPEN</p>
    /// Our hierarchical data item: A Person has Subordinates of type Person.
    /// <p>DOC-SUMMARY-TAG-CLOSE</p>
    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:

C1OrgChart for WPF

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

C1OrgChart for WPF