Data Binding in WinUI TreeGrid
14 Apr 202117 minutes to read
SfTreeGrid is designed to display the self-relational and hierarchical data in tree structure with columns. The data binding can be achieved by assigning the data source to SfTreeGrid.ItemsSource property directly through self-relational binding or nested collection or retrieving the parent and child nodes items dynamically using RequestTreeItems event or LoadOnDemandCommand command.
If the data source implements INotifyCollectionChanged interface, then SfTreeGrid control will automatically refresh the UI when item is added, removed or while list cleared. When you add, remove item in ObservableCollection, SfTreeGrid automatically refresh the UI as ObservableCollection
implements INotifyCollectionChanged
. But when you do the same in List, SfTreeGrid will not refresh the UI automatically.
Below are the ways to bind the data source to SfTreeGrid.
- Populate data using self-relational binding
- Populate data using nested collection
- Populate data with
RequestTreeItems
event - Populate data with
LoadOnDemandCommand
Binding with IEnumerable
SfTreeGrid control supports to bind any collection that implements the IEnumerable interface. Data operations such as sorting is supported when you are binding collection derived from IEnumerable
.
Binding with dynamic data object
SfTreeGrid control supports to bind dynamic data object. Below are the limitations when you are binding dynamic data object,
- In UWP, UI won’t get refreshed when you are changing the property value. This is limitation in UWP platform.
- SfTreeGrid doesn’t support LiveNodeUpdateMode -
AllowDataShaping
.
Binding Complex properties
SfTreeGrid control provides support to bind complex property to its columns. To bind the complex property to TreeGridColumn
, set the complex property path to MappingName
.
xmlns:treeGrid="using:Syncfusion.UI.Xaml.TreeGrid"
<treeGrid:SfTreeGrid x:Name="sfTreeGrid"
ChildPropertyName="Children"
ItemsSource="{Binding PersonDetails}"
ShowRowHeader="True">
<treeGrid:SfTreeGrid.Columns>
<treeGrid:TreeGridColumns>
<treeGrid:TreeGridTextColumn MappingName="FirstName" />
<treeGrid:TreeGridTextColumn MappingName="Address.City" />
<treeGrid:TreeGridTextColumn MappingName="Address.Country" />
</treeGrid:TreeGridColumns>
</treeGrid:SfTreeGrid.Columns>
</treeGrid:SfTreeGrid>
Limitations when binding complex property:
SfTreeGrid doesn’t support LiveNodeUpdateMode
- AllowDataShaping
.
Binding Indexer properties
SfTreeGrid control provides support to bind an indexer property to its columns. To bind an indexer property to TreeGridColumn
, set the indexer property path to MappingName
.
<treeGrid:SfTreeGrid x:Name="sfTreeGrid"
AutoGenerateColumns="False"
ItemsSource="{Binding Employees}">
<treeGrid:SfTreeGrid.Columns>
<treeGrid:TreeGridTextColumn MappingName="FirstName" />
<treeGrid:TreeGridTextColumn MappingName="LastName" />
<treeGrid:TreeGridTextColumn MappingName="ShippersInfo[0].ShipperID" />
</treeGrid:SfTreeGrid.Columns>
</treeGrid:SfTreeGrid>
this.sfTreeGrid.Columns.Add(new TreeGridTextColumn() {MappingName="ShippersInfo[0].ShipperID"});
Limitations when binding Indexer property:
SfTreeGrid doesn’t support LiveNodeUpdateMode
- AllowDataShaping
.
AutoExpandMode
By setting SfTreeGrid.AutoExpandMode property, you can let the SfTreeGrid to expand the nodes while loading.
Mode |
Description |
AllNodesExpanded | All the nodes will be expanded while at the time of loading. |
None | None defines the node is not expanded when loading. By default, root nodes only will be displayed. |
RootNodeExpanded | Root nodes only will be expanded at the time of loading. |
<treeGrid:SfTreeGrid Name="sfTreeGrid"
AutoExpandMode="AllNodesExpanded"
AutoGenerateColumns="False"
ChildPropertyName="ReportsTo"
ItemsSource="{Binding Employees}"
ParentPropertyName="ID" />
this.sfTreeGrid.AutoExpandMode = AutoExpandMode.AllNodesExpanded;
Expanding a tree node
You can expand a node based on its level or row index. Here is a list of ways to expand a node,
Method |
Description |
Expands all the nodes including its inner leaf nodes | |
Expand all the nodes up to the specified level | |
Expand the specific node and its child nodes | |
Expand a node at the specific row Index | |
Expands the specific node. |
Expand all the nodes
You can expand all the nodes programmatically at runtime by using SfTreeGrid.ExpandAllNodes
method.
this.sfTreeGrid.ExpandAllNodes();
Expand the nodes based on its level
You can expand the nodes based on the level by using SfTreeGrid.ExpandAllNodes
method by passing level as argument.
this.sfTreeGrid.ExpandAllNodes(1);
Expand the specific node
You can expand the specific node by using SfTreeGrid.ExpandNode
method.
var node = sfTreeGrid.View.Nodes[0];
this.sfTreeGrid.ExpandNode(node);
You can expand the node at specific index also by using SfTreeGrid.ExpandNode
method.
this.sfTreeGrid.ExpandNode(2);
Expand the specific node based on business object
You can expand the node corresponding to specific data object by resolving node and calling SfTreeGrid.ExpandNode
method.
var data = (this.DataContext as EmployeeViewModel).Employees[0];
var node = this.sfTreeGrid.View.Nodes.GetNode(data);
this.sfTreeGrid.ExpandNode(node);
Expand all the nodes
You can expand the specific node and all its child nodes by using SfTreeGrid.ExpandAllNodes
methods.
var node = sfTreeGrid.View.Nodes[0];
this.sfTreeGrid.ExpandAllNodes(node);
Cancel the node Expanding using NodeExpanding event
You can cancel the node expanding through SfTreeGrid.NodeExpanding event.
this.sfTreeGrid.NodeExpanding += SfTreeGrid_NodeExpanding;
private void SfTreeGrid_NodeExpanding(object sender, NodeExpandingEventArgs e)
{
e.Cancel = true;
}
You can cancel the specific node being expanded by using SfTreeGrid.NodeExpanding
event and Node property,
this.sfTreeGrid.NodeExpanding += SfTreeGrid_NodeExpanding;
private void SfTreeGrid_NodeExpanding(object sender, NodeExpandingEventArgs e)
{
if ((e.Node.Item as Employee).EmpID == 2)
e.Cancel = true;
}
NodeExpanded Event
You can get the notification once a node is expanded from TreeGrid.NodeExpanded event and here you can get the expanded node and its child nodes.
this.sfTreeGrid.NodeExpanded += SfTreeGrid_NodeExpanded;
private void SfTreeGrid_NodeExpanded(object sender, NodeExpandedEventArgs e)
{
var node = e.Node;
var childNodes = e.Node.ChildNodes;
}
Collapsing a tree node
You can collapse all the tree nodes or specific node and its child nodes. Here is a list of ways to collapse a node,
Method |
Description |
Collapse all the nodes in SfTreeGrid | |
Collapse the specific node and its child nodes | |
Collapse the node at specific row index | |
Collapse the specific node in SfTreeGrid |
Collapse all the nodes
You can collapse all the nodes programmatically at runtime by using SfTreeGrid.CollapseAllNodes
methods
this.sfTreeGrid.CollapseAllNodes();
Collapse the specific node
You can collapse the specific node by using SfTreeGrid.CollapseNode
method.
var node = this.sfTreeGrid.View.Nodes[0];
this.sfTreeGrid.CollapseNode(node);
You can collapse the node at specific index also by using SfTreeGrid.CollapseNode
method.
this.sfTreeGrid.CollapseNode(2);
Collapse the specific node based on business object
You can collapse the node corresponding to specific data object by resolving node and calling SfTreeGrid.CollapseNode
method.
var data = (this.DataContext as EmployeeViewModel).Employees[0];
var node = this.sfTreeGrid.View.Nodes.GetNode(data);
this.sfTreeGrid.CollapseNode(node);
Collapse all the nodes
You can collapse the specific node and all its child nodes by using SfTreeGrid.CollapseAllNodes
methods.
var node = this.sfTreeGrid.View.Nodes[0];
this.sfTreeGrid.CollapseAllNodes(node);
Cancel the node collapsing using NodeCollapsing Event
You can cancel the node collapsing operation through TreeGrid.NodeCollapsing event.
this.sfTreeGrid.NodeCollapsing += SfTreeGrid_NodeCollapsing;
private void SfTreeGrid_NodeCollapsing(object sender, NodeCollapsingEventArgs e)
{
e.Cancel = true;
}
You can cancel the specific node being collapsed by using TreeGrid.NodeCollapsing
event.
this.sfTreeGrid.NodeCollapsing += SfTreeGrid_NodeCollapsing;
private void SfTreeGrid_NodeCollapsing(object sender, NodeCollapsingEventArgs e)
{
if ((e.Node.Item as Employee).EmpID == 2)
e.Cancel = true;
}
NodeCollapsed Event
You can get the notification once a node is collapsed from TreeGrid.NodeCollapsed event and here you can get the collapsed node.
this.sfTreeGrid.NodeCollapsed += SfTreeGrid_NodeCollapsed;
private void SfTreeGrid_NodeCollapsed(object sender, NodeCollapsedEventArgs e)
{
var node = e.Node;
}
Expand/Collapse a node based on mapping property
SfTreeGrid supports to expand/collapse the nodes based on the value of a boolean mapping property in the underlying data object by using SfTreeGrid.ExpandStateMappingName property. TreeGrid expand/collapse the node when the specified property value in underlying data object gets changed.
<treeGrid:SfTreeGrid Name="sfTreeGrid"
ExpandStateMappingName="IsExpanded"
ChildPropertyName="Children"
ItemsSource="{Binding PersonDetails}"
ShowCheckBox="True" />
this.sfTreeGrid.ExpandStateMappingName = "IsExpanded";
LiveNodeUpdateMode
SfTreeGrid listens and responds to the manipulation such as add, delete and data update (property change) at runtime. SfTreeGrid refreshes the sorting based on SfTreeGrid.LiveNodeUpdateMode
property. If you set LiveNodeUpdateMode
as AllowDataShaping
, sorting will be refreshed on data manipulation and property change.
<treeGrid:SfTreeGrid Name="sfTreeGrid"
AllowEditing="True"
AutoExpandMode="RootNodesExpanded"
LiveNodeUpdateMode="AllowDataShaping"
AutoGenerateColumns="False"
ChildPropertyName="ReportsTo"
ItemsSource="{Binding Employees}"
ParentPropertyName="ID" />
this.sfTreeGrid.LiveNodeUpdateMode = LiveNodeUpdateMode.AllowDataShaping;
Events
ItemsSourceChanged
SfTreeGrid.ItemsSourceChanged event occurs when the data source is changed by using ItemsSource property.
This event receives two arguments namely sender that handles SfTreeGrid and TreeGridItemsSourceChangedEventArgs as objects.
The TreeGridItemsSourceChangedEventArgs
object contains the following properties:
- OldItemsSource - Gets the value of old data source
- NewItemsSource - Get the value of new data source
View
SfTreeGrid has the View property of type TreeGridView. View
is responsible for maintaining and manipulating the nodes and other advanced operations like Sorting. When you bind Collection to ItemsSource
property of SfTreeGrid or wire RequestTreeItems
event, then View
will be created and maintains the operations on nodes.
SfTreeGrid creates different types of views derived from TreeGridView based on data population methods.
TreeGridSelfRelationalView - While populating data using self-relational binding.
TreeGridNestedView - While populating data using nested collection.
TreeGridUnboundView - While populating data with RequestTreeItems
event or LoadOnDemandCommand
command.
Events
The following events are associated with View.
RecordPropertyChanged
This event is raised when the DataModel property value is changed, if the DataModel implements the INotifyPropertyChanged interface. The event receives with two arguments namely sender
that handles the DataModel and PropertyChangedEventArgs
as object.
PropertyChangedEventArgs
has below property,
PropertyName
– It denotes the PropertyName of the changed value.
NodeCollectionChanged
This event is raised whenever there is some change in nodes collection. The event receives two arguments namely sender that handles View
object and NotifyCollectionChangedEventArgs
as object.
NotifyCollectionChangedEventArgs
has below properties,
-
Action
- It contains the current action. (i.e.) Add, Remove, Move, Replace, Reset. -
NewItems
- It contains the list of new items involved in the change. -
OldItems
- It contains the list of old items affected by the Action. -
NewStartingIndex
- It contains the index at which the change occurred. -
OldStartingIndex
- It contains the index at which the Action occurred.
SourceCollectionChanged
This event is raised when you make changes in SourceCollection
for example add or remove the collection. The event receives two arguments namely sender that handles that handles View
object and NotifyCollectionChangedEventArgs
as object.
NotifyCollectionChangedEventArgs
has below properties,
-
Action
- It contains the current action. (i.e) Add, Remove, Move, Replace, Reset. -
NewItems
- It contains the list of new items involved in the change. -
OldItems
- It contains the list of old items affected by the Action. -
NewStartingIndex
- It contains the index at which the change occurred. -
OldStartingIndex
- It contains the index at which the Action occurred.
Methods
The following are the methods that are associated with View
which can be used to defer refresh the view.
DeferRefresh
Enter the defer cycle so that you can perform all data operations in view and update once. You can refresh the nodes or completely recreates the nodes by using TreeViewRefreshMode parameter.
using (this.sfTreeGrid.View.DeferRefresh(TreeViewRefreshMode.NodeRefresh))
{
this.sfTreeGrid.SortColumnDescriptions.Add(new SortColumnDescription() { ColumnName = "FirstName", SortDirection = ListSortDirection.Descending });
this.sfTreeGrid.SortColumnDescriptions.Add(new SortColumnDescription() { ColumnName = "ID", SortDirection = ListSortDirection.Descending });
}
BeginInit and EndInit
When BeginInit method is called, it suspends all the updates until EndInit method is called. You can perform all the update with in these methods and update the view at once. You can refresh the nodes or completely recreates the nodes by using TreeViewRefreshMode
parameter.
this.sfTreeGrid.View.BeginInit(TreeViewRefreshMode.DeferRefresh);
this.sfTreeGrid.SortColumnDescriptions.Add(new SortColumnDescription() { ColumnName = "FirstName", SortDirection = ListSortDirection.Descending });
this.sfTreeGrid.SortColumnDescriptions.Add(new SortColumnDescription() { ColumnName = "ID", SortDirection = ListSortDirection.Descending });
this.sfTreeGrid.View.EndInit();
NOTE
View has properties (EnableRecursiveChecking,
LiveNodeUpdateMode
, RecursiveCheckingMode,..)that already defined in SfTreeGrid. It is recommended to set those properties via SfTreeGrid.