How to resize the row based on the height of multi-line textbox entry in WPF DataGrid (SfDataGrid)?
You can automatically increase the height of a row when typing multiline text in the text box of GridTemplateColumn using the QueryRowHeight event in WPF DataGrid (SfDataGrid).
In the sample, the height of a row is increased after editing the text box of GridTemplateColumn.
XAML
<syncfusion:SfDataGrid x:Name="grid"
RowHeight="24"
ShowRowHeader="True"
AllowEditing="True"
AllowGrouping="True"
ShowGroupDropArea="True"
ItemsSource="{Binding Emp}">
<interactivity:Interaction.Behaviors>
<local:SfDataGridBehavior/>
</interactivity:Interaction.Behaviors>
<syncfusion:SfDataGrid.Resources>
<ResourceDictionary>
<Style TargetType="TextBox">
<Setter Property="AcceptsReturn"
Value="True" />
</Style>
</ResourceDictionary>
</syncfusion:SfDataGrid.Resources>
<syncfusion:SfDataGrid.Columns>
<syncfusion:GridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding EmployeeInfo}" TextWrapping="Wrap" />
</DataTemplate>
</syncfusion:GridTemplateColumn.CellTemplate>
<syncfusion:GridTemplateColumn.EditTemplate>
<DataTemplate>
<TextBox AcceptsReturn="True" ScrollViewer.VerticalScrollBarVisibility="Visible" TextWrapping="Wrap" Text="{Binding EmployeeInfo,Mode=TwoWay}" />
</DataTemplate>
</syncfusion:GridTemplateColumn.EditTemplate>
</syncfusion:SfDataGrid.Columns>
</syncfusion:SfDataGrid>
datagrid.QueryRowHeight += datagrid_QueryRowHeight;
private void datagrid_QueryRowHeight(object sender, QueryRowHeightEventArgs e)
{
if (this.datagrid.GridColumnSizer.GetAutoRowHeight(e.RowIndex, gridRowResizingOptions, out Height))
{
// Reset the Height of the row to datagrid row height when the row height is less than the datagrid row height.
if (Height < datagrid.RowHeight)
{
Height = datagrid.RowHeight;
}
e.Height = Height;
e.Handled = true;
}
}
The CurrentCellValueChanged event will be triggered when editing a particular cell. So, you can change the row height by calling the SfDataGrid.InvalidateRowHeight and VisualContainer.InvalidateMeasureInfo methods.
datagrid.CurrentCellValueChanged += datagrid_CurrentCellValueChanged;
private void datagrid_CurrentCellValueChanged(object sender, CurrentCellValueChangedEventArgs args)
{
datagrid.InvalidateRowHeight(args.RowColumnIndex.RowIndex);
datagrid.GetVisualContainer().InvalidateMeasureInfo();
}
You can measure the text height when editing the text box of GridTemplateColumn using the GridColumnSizer.MeasureTemplate method.
public class GridColumnAutoSizerExt : GridColumnSizer
{
public GridColumnAutoSizerExt(SfDataGrid grid): base(grid)
{
}
protected override Size MeasureTemplate(Size rect, object record, GridColumn column, GridQueryBounds bounds)
{
var data = record.GetType().GetProperty(column.MappingName).GetValue(record);
var datatext = Convert.ToString(data);
FormattedText formattedtext = GetFormattedText(column, record, datatext);
formattedtext.Trimming = TextTrimming.None;
formattedtext.MaxTextWidth = this.DataGrid.GetVisualContainer().ColumnWidths.DefaultLineSize;
formattedtext.MaxTextHeight = double.MaxValue;
if (formattedtext.MaxTextWidth > (Margin.Left + Margin.Right))
formattedtext.MaxTextWidth -= (Margin.Left + Margin.Right);
return new Size(formattedtext.Width, formattedtext.Height);
}
}
In WPF, you can get the formatted text height by using the following code snippet.
private FormattedText GetFormattedText(GridColumn column, object record, string datatext)
{
FormattedText formattedtext;
formattedtext = new FormattedText(datatext, System.Globalization.CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface(DataGrid.FontFamily, new FontStyle(), FontWeights.Normal, DataGrid.FontStretch), DataGrid.FontSize, Brushes.Black);
return formattedtext;
}
In UWP, you can get the formatted text height by using the following code snippet.
protected override Size MeasureTemplate(Size rect, object record, GridColumn column, GridQueryBounds bounds)
{
var data = record.GetType().GetProperty(column.MappingName).GetValue(record);
var datatext = Convert.ToString(data);
return GetTextHeight(datatext);
}
private Size GetTextHeight(string dataText)
{
TextBlock textBlock = new TextBlock { Text = dataText, FontSize = DataGrid.FontSize, FontFamily = DataGrid.FontFamily, FontStretch = DataGrid.FontStretch, FontStyle = new FontStyle(), FontWeight = FontWeights.Normal, FlowDirection = FlowDirection.LeftToRight };
textBlock.Measure(new Size(Double.PositiveInfinity, double.PositiveInfinity));
Size defaultFormattedText = textBlock.DesiredSize;
return defaultFormattedText;
}