Error when changing the width when scrolling a column that is frozen
Hello, I have a problem when I want to adjust the width of a frozen column when scrolling, so that it does not occupy the same space when you scroll horizontally.
.Net 8
Syncfusion.Maui.DataGrid 26.2.11
This is my xaml code, I also put what layout it is in in case it has any relevance.
<ContentView.Resources>
<ResourceDictionary>
<Style x:Key="BoxViewShimmerStyle" TargetType="BoxView">
<Setter Property="Margin" Value="8" />
<Setter Property="CornerRadius" Value="8" />
<Setter Property="HeightRequest" Value="24" />
<Setter Property="VerticalOptions" Value="Center" />
<Setter Property="HorizontalOptions" Value="FillAndExpand" />
<Setter Property="BackgroundColor" Value="{DynamicResource NeutralGrey400}" />
</Style>
</ResourceDictionary>
</ContentView.Resources>
<shimmer:SfShimmer
WaveColor="{DynamicResource NeutralWhite_WaveColor}"
IsActive="{Binding IsLoading, Source={x:Reference ControlReference}}">
<shimmer:SfShimmer.CustomView>
<Grid
Padding="0"
RowSpacing="0"
ColumnSpacing="0"
RowDefinitions="Auto,Auto"
ColumnDefinitions="*,*,*,*"
BackgroundColor="{DynamicResource ShimmerBackgroundColor}">
<BoxView
Grid.Row="0"
Grid.Column="0"
Style="{StaticResource BoxViewShimmerStyle}" />
<BoxView
Grid.Row="0"
Grid.Column="1"
Style="{StaticResource BoxViewShimmerStyle}" />
<BoxView
Grid.Row="0"
Grid.Column="2"
Style="{StaticResource BoxViewShimmerStyle}" />
<BoxView
Grid.Row="0"
Grid.Column="3"
Style="{StaticResource BoxViewShimmerStyle}" />
<BoxView
Grid.Row="1"
Grid.Column="0"
Style="{StaticResource BoxViewShimmerStyle}" />
<BoxView
Grid.Row="1"
Grid.Column="1"
Style="{StaticResource BoxViewShimmerStyle}" />
<BoxView
Grid.Row="1"
Grid.Column="2"
Style="{StaticResource BoxViewShimmerStyle}" />
<BoxView
Grid.Row="1"
Grid.Column="3"
Style="{StaticResource BoxViewShimmerStyle}" />
</Grid>
</shimmer:SfShimmer.CustomView>
<shimmer:SfShimmer.Content>
<datagrid:SfDataGrid
x:Name="dataGrid"
DataGridLoaded="DataGrid_OnDataGridLoaded"
FrozenColumnCount="1"
RowHeight="56"
ColumnWidthMode="Auto"
HeaderRowHeight="40"
ShowRowHeader="False"
SortingMode="Multiple"
AllowTriStateSorting="True"
AutoGenerateColumnsMode="None"
AllowResizingColumns="False"
BackgroundColor="{DynamicResource NeutralWhite_Black600}">
<datagrid:SfDataGrid.DefaultStyle>
<datagrid:DataGridStyle
HeaderRowBackground="{DynamicResource NeutralWhite_Black}"
HeaderRowFontSize="{DynamicResource NeutralSlate700_NeutralGrey600}"
RowBackground="{DynamicResource NeutralWhite_Black}"
CurrentCellBorderWidth="1"
CurrentCellBorderColor="{DynamicResource NeutralSlate700_NeutralGrey600}"
GridLineColor="{DynamicResource NeutralSlate700_NeutralGrey600}" />
</datagrid:SfDataGrid.DefaultStyle>
<datagrid:SfDataGrid.SortIconTemplate>
<DataTemplate>
<Image Source="{x:Static constants:IconConstants.SortAsc}" />
</DataTemplate>
</datagrid:SfDataGrid.SortIconTemplate>
<datagrid:SfDataGrid.Columns>
<datagrid:DataGridTemplateColumn
x:DataType="models:HoldingItemModel"
x:Name="recordColumn"
CellPadding="0"
Width="90"
ValueBinding="{Binding TickerName}">
<datagrid:DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<StackLayout
Spacing="0"
Padding="8,0,12,0">
<Label
Text="{Binding NameHeader, Source={x:Reference ControlReference}}"
Style="{Binding ColumnHeaderStyle, Source={x:Reference ControlReference}}">
<Label.Triggers>
<DataTrigger TargetType="Label"
Binding="{Binding Width, Source={x:Reference recordColumn}}"
Value="40">
<Setter Property="IsVisible" Value="False" />
</DataTrigger>
</Label.Triggers>
</Label>
</StackLayout>
</DataTemplate>
</datagrid:DataGridTemplateColumn.HeaderTemplate>
<datagrid:DataGridTemplateColumn.CellTemplate>
<DataTemplate
x:DataType="models:HoldingItemModel">
<StackLayout
Spacing="0"
Padding="8,0">
<Label
Style="{Binding ColumnTextStyle, Source={x:Reference ControlReference}}"
Text="{Binding TickerName}">
<Label.Triggers>
<DataTrigger TargetType="Label"
Binding="{Binding Width, Source={x:Reference recordColumn}}"
Value="40">
<Setter Property="IsVisible" Value="False" />
</DataTrigger>
</Label.Triggers>
</Label>
<Label
Style="{Binding ColumnTextStyle, Source={x:Reference ControlReference}}"
Text="{Binding CompanyName}" FontAttributes="None">
<Label.Triggers>
<DataTrigger TargetType="Label"
Binding="{Binding Width, Source={x:Reference recordColumn}}"
Value="40">
<Setter Property="IsVisible" Value="False" />
</DataTrigger>
</Label.Triggers>
</Label>
<Border
Padding="0"
Margin="0,8"
IsVisible="False"
WidthRequest="24"
HeightRequest="48"
VerticalOptions="Center"
HorizontalOptions="Center"
BackgroundColor="{DynamicResource NeutralSlate700_NeutralSlate700}">
<Border.StrokeShape>
<RoundRectangle CornerRadius="8"/>
</Border.StrokeShape>
<Border.Triggers>
<DataTrigger TargetType="Border"
Binding="{Binding Width, Source={x:Reference recordColumn}}"
Value="40">
<Setter Property="IsVisible" Value="True" />
</DataTrigger>
</Border.Triggers>
<Label
Style="{StaticResource Medium25Label}"
Rotation="270"
VerticalTextAlignment="Center"
HorizontalTextAlignment="Center"
TextColor="{DynamicResource NeutralSlate300_NeutralSlate300}"
Text="{Binding TickerName}" />
</Border>
</StackLayout>
</DataTemplate>
</datagrid:DataGridTemplateColumn.CellTemplate>
</datagrid:DataGridTemplateColumn>
<datagrid:DataGridTemplateColumn
x:DataType="models:HoldingItemModel"
CellPadding="0"
HeaderPadding="0"
MinimumWidth="120"
ValueBinding="{Binding SecurityType}">
<datagrid:DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<StackLayout
Spacing="0"
Padding="8,0,12,0">
<Label
Text="{Binding SecurityTypeHeader, Source={x:Reference ControlReference}}"
Style="{Binding ColumnHeaderStyle, Source={x:Reference ControlReference}}" />
</StackLayout>
</DataTemplate>
</datagrid:DataGridTemplateColumn.HeaderTemplate>
<datagrid:DataGridTemplateColumn.CellTemplate>
<DataTemplate
x:DataType="models:HoldingItemModel">
<StackLayout
Spacing="0"
Padding="8,0">
<Label
Style="{Binding ColumnTextStyle, Source={x:Reference ControlReference}}"
Text="{Binding SecurityType}" />
</StackLayout>
</DataTemplate>
</datagrid:DataGridTemplateColumn.CellTemplate>
</datagrid:DataGridTemplateColumn>
<datagrid:DataGridTemplateColumn
x:DataType="models:HoldingItemModel"
CellPadding="0"
HeaderPadding="0"
MinimumWidth="120"
ValueBinding="{Binding Quantity}">
<datagrid:DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<StackLayout
Spacing="0"
Padding="8,0,12,0">
<Label
Text="{Binding QuantityHeader, Source={x:Reference ControlReference}}"
Style="{Binding ColumnHeaderStyle, Source={x:Reference ControlReference}}"
HorizontalTextAlignment="End" />
</StackLayout>
</DataTemplate>
</datagrid:DataGridTemplateColumn.HeaderTemplate>
<datagrid:DataGridTemplateColumn.CellTemplate>
<DataTemplate
x:DataType="models:HoldingItemModel">
<StackLayout
Spacing="0"
Padding="8,0">
<Label
Style="{Binding ColumnTextStyle, Source={x:Reference ControlReference}}"
Text="{Binding Quantity, TargetNullValue='--'}" HorizontalTextAlignment="End" />
</StackLayout>
</DataTemplate>
</datagrid:DataGridTemplateColumn.CellTemplate>
</datagrid:DataGridTemplateColumn>
<datagrid:DataGridTemplateColumn
x:DataType="models:HoldingItemModel"
CellPadding="0"
HeaderPadding="0"
MinimumWidth="120"
ValueBinding="{Binding AvgCostBasis}">
<datagrid:DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<StackLayout
Spacing="0"
Padding="8,0,12,0">
<Label
Text="{Binding AvgCostBasisHeader, Source={x:Reference ControlReference}}"
Style="{Binding ColumnHeaderStyle, Source={x:Reference ControlReference}}"
HorizontalTextAlignment="End" />
</StackLayout>
</DataTemplate>
</datagrid:DataGridTemplateColumn.HeaderTemplate>
<datagrid:DataGridTemplateColumn.CellTemplate>
<DataTemplate
x:DataType="models:HoldingItemModel">
<StackLayout
Spacing="0"
Padding="8,0">
<Label
Style="{Binding ColumnTextStyle, Source={x:Reference ControlReference}}"
Text="{Binding AvgCostBasis, StringFormat='{0:C2}', TargetNullValue='$--'}"
HorizontalTextAlignment="End" />
</StackLayout>
</DataTemplate>
</datagrid:DataGridTemplateColumn.CellTemplate>
</datagrid:DataGridTemplateColumn>
</datagrid:SfDataGrid.Columns>
</datagrid:SfDataGrid>
</shimmer:SfShimmer.Content>
</shimmer:SfShimmer>
As you can see, what is done is to hide the column label and rotate it so that it takes up less space and put it inside a border.
Below I show the code that I believe belongs to the part of the code behind where the scroll event is shown and you can see that the width change is executed.
private VisualContainer _container;
/// <summary>
/// DataGrid_OnDataGridLoaded
/// </summary>
/// <param name="sender">Sender</param>
/// <param name="e">EventArgs</param>
private void DataGrid_OnDataGridLoaded(object? sender, EventArgs e)
{
_container = dataGrid.GetVisualContainer();
if (_container == null)
{
return;
}
_container.ScrollColumns.Changed += OnScrollColumnsChanged;
}
/// <summary>
/// OnScrollColumnsChanged
/// </summary>
/// <param name="sender">Sender</param>
/// <param name="e">EventArgs</param>
private void OnScrollColumnsChanged(object sender, ScrollChangedEventArgs e)
{
var hOffset = _container?.HorizontalOffset;
if (hOffset > 90)
{
return;
}
if (hOffset == 0)
{
recordColumn.Width = 90;
recordColumn.AllowSorting = true;
}
else if (recordColumn.Width != 40)
{
recordColumn.Width = 40;
recordColumn.AllowSorting = false;
}
}
This is the error
System.StackOverflowException: The requested operation caused a stack overflow.
at Microsoft.Maui.Controls.SetterSpecificityList.SetValue(SetterSpecificity specificity, Object value)
at Microsoft.Maui.Controls.SetterSpecificityList.set_Item(SetterSpecificity key, Object value)
at Microsoft.Maui.Controls.BindableObject.SetValueActual(BindableProperty property, BindablePropertyContext context, Object value, Boolean currentlyApplying, SetValueFlags attributes, SetterSpecificity specificity, Boolean silent)
at Microsoft.Maui.Controls.BindableObject.SetValueCore(BindableProperty property, Object value, SetValueFlags attributes, SetValuePrivateFlags privateAttributes, SetterSpecificity specificity)
at Microsoft.Maui.Controls.BindableObject.SetValue(BindableProperty property, Object value)
at Syncfusion.Maui.DataGrid.DataGridColumn.set_ActualWidth(Double value)
at Syncfusion.Maui.DataGrid.DataGridColumnSizer.GetActualWidth(DataGridColumn column, Double calculatedWidth)
at Syncfusion.Maui.DataGrid.DataGridColumnSizer.GetColumnWidth(DataGridColumn column, Double width)
at Syncfusion.Maui.DataGrid.DataGridColumnSizer.CalculateColumnSizerWidth(Double viewSize)
at Syncfusion.Maui.DataGrid.DataGridColumnSizer.Refresh(Double viewSize)
at Syncfusion.Maui.DataGrid.DataGridColumnSizer.Refresh(Boolean needsLayout)
at Syncfusion.Maui.DataGrid.DataGridColumnSizer.OnColumnPropertyChanged(DataGridColumn column, String propertyName)
at Syncfusion.Maui.DataGrid.DataGridColumn.set_Width(Double value)
at Axos.Udb.Mobile.UIControls.Controls.Table.HoldingsTable.OnScrollColumnsChanged(Object sender, ScrollChangedEventArgs e) in /HoldingsTable.xaml.cs:line 278
at Syncfusion.Maui.GridCommon.ScrollAxis.ScrollAxisBase.RaiseChanged(ScrollChangedAction action)
at Syncfusion.Maui.GridCommon.ScrollAxis.ScrollAxisBase.ScrollLinesHost_LineHiddenChanged(Object sender, HiddenRangeChangedEventArgs e)
at Syncfusion.Maui.GridCommon.ScrollAxis.LineSizeCollection.ResumeUpdates()
at Syncfusion.Maui.DataGrid.DataGridColumnSizer.Refresh(Boolean needsLayout)
at Syncfusion.Maui.DataGrid.DataGridColumnSizer.OnColumnPropertyChanged(DataGridColumn column, String propertyName)
at Syncfusion.Maui.DataGrid.DataGridColumn.set_Width(Double value)
at Axos.Udb.Mobile.UIControls.Controls.Table.HoldingsTable.OnScrollColumnsChanged(Object sender, ScrollChangedEventArgs e) in HoldingsTable.xaml.cs:line 278
at Syncfusion.Maui.GridCommon.ScrollAxis.ScrollAxisBase.RaiseChanged(ScrollChangedAction action)
at Syncfusion.Maui.GridCommon.ScrollAxis.ScrollAxisBase.ScrollLinesHost_LineHiddenChanged(Object sender, HiddenRangeChangedEventArgs e)
at Syncfusion.Maui.GridCommon.ScrollAxis.LineSizeCollection.ResumeUpdates()
at Syncfusion.Maui.DataGrid.DataGridColumnSizer.Refresh(Boolean needsLayout)
at Syncfusion.Maui.DataGrid.DataGridColumnSizer.OnColumnPropertyChanged(DataGridColumn column, String propertyName)
at Syncfusion.Maui.DataGrid.DataGridColumn.set_Width(Double value)
at Axos.Udb.Mobile.UIControls.Controls.Table.HoldingsTable.OnScrollColumnsChanged(Object sender, ScrollChangedEventArgs e)
Hi Rahul Daniel,
We have reviewed the provided code snippets. The StackOverflow exception is caused by the following reason: Previously, you had wired the _container.ScrollColumns.Changed event. This event is triggered whenever any changes occur in the column, and inside the event, you had redefined the width of the column. This recursive call triggers the event in an infinite loop, resulting in a StackOverflow exception.
In this case, the _container.ScrollOwner.Scrolled event suits your needs.
Kindly replace the _container.ScrollColumns.Changed with _container.ScrollOwner.Scrolled in your sample and check if the issue is resolved on your end. If the reported issue persists, please provide us with a simple sample that replicates the issue you are facing.
Code snippet:
|
private void DataGrid_OnDataGridLoaded(object sender, EventArgs e) { _container = dataGrid.GetVisualContainer();
if (_container == null) {
return; }
_container.ScrollOwner.Scrolled += ScrollOwner_Scrolled; }
private void ScrollOwner_Scrolled(object? sender, ScrolledEventArgs e) { var hOffset = _container?.HorizontalOffset;
if (hOffset > 90) { return; }
if (hOffset == 0) { recordColumn.Width = 90;
recordColumn.AllowSorting = true; }
else if (recordColumn.Width != 40) { recordColumn.Width = 40;
recordColumn.AllowSorting = false; } } |
Regards,
Sethupathy D.
- 1 Reply
- 2 Participants
- Marked answer
-
RD Raul Daniel Pimienta Ramos
- Dec 21, 2024 12:48 AM UTC
- Dec 23, 2024 10:12 AM UTC