Column Sizing in WinUI TreeGrid
29 Apr 20229 minutes to read
SfTreeGrid allows you to set the column widths based on certain logic using SfTreeGrid.ColumnWidthMode or TreeGridColumn.ColumnWidthMode property.
Below is the list of predefined column sizing options available.
Type | Column width |
---|---|
Star
|
Divides the total width equally for columns. |
Auto
|
Calculates the width of column based on header and cell contents. So that header and cell content's are not truncated. |
AutoLastColumnFill
|
The size is based on the contents of both the cells and the column header with last column auto fill. The column to be filled can be any column. |
AutoWithLastColumnFill
|
The size is based on the contents of both the cells and the column header with last column fill by default. The column to be filled can be any column. |
SizeToCells
|
Calculates the width of column based on cell contents. So that cell content's are not truncated. |
SizeToHeader
|
Calculates the width of column based on header content. So that header content is not truncated. |
None
|
Default column width or defined width set to column. |
NOTE
ColumnWidthMode will not work when the column width defined explicitly. ColumnWidthMode calculates column width based on
MinWidth
andMaxWidth
properties.
Below code, applies GridLengthUnitType.Star
to equally set width for SfTreeGrid.Columns
.
<treeGrid:SfTreeGrid Name="treeGrid"
AllowEditing="True"
ColumnWidthMode="Star"
AutoExpandMode="AllNodesExpanded"
AutoGenerateColumns="False"
ChildPropertyName="ReportsTo"
ItemsSource="{Binding Employees}"
ParentPropertyName="ID"
SelfRelationRootValue="-1" >
<treeGrid:SfTreeGrid.Columns>
<treeGrid:TreeGridTextColumn HeaderText="First Name" MappingName="FirstName" />
<treeGrid:TreeGridTextColumn HeaderText="Last Name" MappingName="LastName" />
<treeGrid:TreeGridNumericColumn HeaderText="Employee ID" MappingName="ID" />
<treeGrid:TreeGridTextColumn HeaderText="Title" MappingName="Title" />
<treeGrid:TreeGridNumericColumn HeaderText="Salary" MappingName="Salary" DisplayNumberFormat="C2"/>
<treeGrid:TreeGridNumericColumn HeaderText="Reports To" MappingName="ReportsTo" />
</treeGrid:SfTreeGrid.Columns>
</treeGrid:SfTreeGrid>
NOTE
The
TreeGridColumn.ColumnWidthMode
takes higher priority than theSfTreeGrid.ColumnWidthMode
.
Refreshing ColumnSizer at runtime
You can refresh the ColumnSizer
at runtime by calling SfTreeGrid.ColumnSizer.Refresh method.
SfTreeGrid support to recalculates the column auto width by calling reset methods of ColumnSizer
. ColumnSizer.ResetAutoCalculationforAllColumns method reset widths to all columns. ColumnSizer.ResetAutoCalculation method reset the width to particular column.
NOTE
The
ColumnSizer.ResetAutoCalculationforAllColumns
orColumnSizer.ResetAutoCalculation
methods applicable for Auto, FillColumn, AutoFillColumn, SizeToCells types.
For example, you can refresh all the column's width based on the cell contents of newly added records at runtime.
var viewModel = this.treeGrid.DataContext as ViewModel;
viewModel.PersonDetails.Add(new PersonInfo("Smith", "Anders","Red", new DateTime(2008, 10, 26), null));
this.treeGrid.ColumnSizer.ResetAutoCalculationforAllColumns();
this.treeGrid.ColumnSizer.Refresh();
Resetting column width to apply ColumnSizer
When the width of the column is explicitly defined or column is resized, then column width is not changed based on TreeGridColumnSizer
. You can reset TreeGridColumn.Width by setting double.NaN
to apply column width based on column sizer.
foreach (var column in treeGrid.Columns)
{
if (!double.IsNaN(column.Width))
column.Width = double.NaN;
}
this.treeGrid.ColumnSizer.Refresh();
Customizing built-in column sizing logic
SfTreeGrid process column sizing operations in TreeGridColumnSizer class. You can customize the column sizing operations by overriding TreeGridColumnSizer
and set it to SfTreeGrid.ColumnSizer
.
this.treeGrid.ColumnSizer = new TreeGridColumnSizerExt(treeGrid);
public class TreeGridColumnSizerExt:TreeGridColumnSizer
{
public TreeGridColumnSizerExt(SfTreeGrid treeGrid)
:base(treeGrid)
{
}
// Calculate Width for column when ColumnSizer is SizeToCells.
protected override double CalculateCellWidth(TreeGridColumn column)
{
return base.CalculateCellWidth(column);
}
//Calculate Width for the column when ColumnSizer is SizeToHeader
protected override double CalculateHeaderWidth(TreeGridColumn column)
{
return base.CalculateHeaderWidth(column);
}
}
Auto width calculation based on font settings
By default, the ColumnSizer calculates column's width based on fixed FontSize
, FontFamily
, Margin
,SortIconWidth
. You can change the calculation by customized settings.
Changing SortIcon width
You can change the filter icon and sort icon widths for column width calculation by setting ColumnSizer.SortIconWidth properties.
this.treeGrid.ColumnSizer.SortIconWidth = 20;
Changing Font settings for SfTreeGrid
You can change the font settings
for column width calculation by setting ColumnSizer.FontSize, ColumnSizer.FontFamily and ColumnSizer.Margin properties. This settings will be considered for all columns.
this.treeGrid.ColumnSizer.FontSize = 10.0;
this.treeGrid.ColumnSizer.FontFamily = new FontFamily("TimesNewRoman");
this.treeGrid.ColumnSizer.Margin = new Thickness(9, 3, 1, 3);
Star column sizer ratio support
You can customize the ColumnWidthMode.Star
width calculation logic by overriding SetStarWidth method of TreeGridColumnSizer.
For example, you can calculate the column width, with specified ratios instead of dividing equal width for all columns in Star calculation using ColumnRatio
attached property.
public static class StarRatio
{
public static int GetColumnRatio(DependencyObject obj)
{
return (int)obj.GetValue(ColumnRatioProperty);
}
public static void SetColumnRatio(DependencyObject obj, int value)
{
obj.SetValue(ColumnRatioProperty, value);
}
public static readonly DependencyProperty ColumnRatioProperty = DependencyProperty.RegisterAttached("ColumnRatio", typeof(int), typeof(StarRatio), new PropertyMetadata(1, null));
}
Below code to define the star width calculation based on the ColumnRatio
.
//Assign the customized TreeGridColumnSizerExt to SfTreeGrid.ColumnSizer
this.treeGrid.ColumnSizer = new TreeGridColumnSizerExt(treeGrid);
public class TreeGridColumnSizerExt : TreeGridColumnSizer
{
public TreeGridColumnSizerExt(SfTreeGrid treeGrid) : base(treeGrid)
{
}
protected override void SetStarWidth(double remainingColumnWidth, IEnumerable<TreeGridColumn> remainingColumns)
{
var removedColumn = new List<TreeGridColumn>();
var columns = remainingColumns.ToList();
var totalRemainingStarValue = remainingColumnWidth;
double removedWidth = 0;
bool isRemoved;
while (columns.Count > 0)
{
isRemoved = false;
removedWidth = 0;
var columnsCount = 0;
columns.ForEach((col) =>
{
columnsCount += StarRatio.GetColumnRatio(col);
});
double starWidth = Math.Floor((totalRemainingStarValue / columnsCount));
var column = columns.First();
starWidth *= StarRatio.GetColumnRatio(column);
double computedWidth = SetColumnWidth(column, starWidth);
if (starWidth != computedWidth && starWidth > 0)
{
isRemoved = true;
columns.Remove(column);
foreach (var remColumn in removedColumn)
{
if (!columns.Contains(remColumn))
{
removedWidth += remColumn.ActualWidth;
columns.Add(remColumn);
}
}
removedColumn.Clear();
totalRemainingStarValue += removedWidth;
}
totalRemainingStarValue = totalRemainingStarValue - computedWidth;
if (!isRemoved)
{
columns.Remove(column);
if (!removedColumn.Contains(column))
removedColumn.Add(column);
}
}
}
}
Below code uses the ColumnRatio
to apply the defined star width for each column.
<treeGrid:SfTreeGrid Name="treeGrid"
AllowEditing="True"
ColumnWidthMode="Star"
AutoExpandMode="AllNodesExpanded"
AutoGenerateColumns="False"
ChildPropertyName="ReportsTo"
ItemsSource="{Binding Employees}"
ParentPropertyName="ID"
SelfRelationRootValue="-1" >
<treeGrid:SfTreeGrid.Columns>
<treeGrid:TreeGridTextColumn HeaderText="First Name"
MappingName="FirstName"
local:StarRatio.ColumnRatio="3" />
<treeGrid:TreeGridTextColumn HeaderText="Last Name"
MappingName="LastName"
local:StarRatio.ColumnRatio="2"/>
<treeGrid:TreeGridNumericColumn HeaderText="Employee ID"
MappingName="ID"
local:StarRatio.ColumnRatio="1" />
<treeGrid:TreeGridNumericColumn HeaderText="Salary" MappingName="Salary" DisplayNumberFormat="C2"/>
<treeGrid:TreeGridNumericColumn HeaderText="Reports To" MappingName="ReportsTo" />
</treeGrid:SfTreeGrid.Columns>
</treeGrid:SfTreeGrid>