From b55b2b547d683d2fcc1c7e133e674d397b6f6393 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20Torsg=C3=A5rden?= Date: Wed, 13 May 2026 18:16:19 +0200 Subject: [PATCH 01/10] Add ColumnAutoWidthMode --- src/ColumnAutoWidthMode.cs | 22 ++++++ src/Columns/TableViewColumn.cs | 14 ++++ src/TableView.Properties.cs | 14 ++++ src/TableViewCell.cs | 122 +++++++++++++++++---------------- src/TableViewColumnHeader.cs | 18 +++++ 5 files changed, 131 insertions(+), 59 deletions(-) create mode 100644 src/ColumnAutoWidthMode.cs diff --git a/src/ColumnAutoWidthMode.cs b/src/ColumnAutoWidthMode.cs new file mode 100644 index 00000000..e036a089 --- /dev/null +++ b/src/ColumnAutoWidthMode.cs @@ -0,0 +1,22 @@ +namespace WinUI.TableView; + +/// +/// Specifies the behavior for automatic column width. +/// +public enum ColumnAutoWidthMode +{ + /// + /// Column width is adjusted to both header and maximum cell width. + /// + Both, + + /// + /// Column width is adjusted to maximum cell width. + /// + Cells, + + /// + /// Column width is adjusted to header width. + /// + Header +} diff --git a/src/Columns/TableViewColumn.cs b/src/Columns/TableViewColumn.cs index 48ae832a..70f50fd5 100644 --- a/src/Columns/TableViewColumn.cs +++ b/src/Columns/TableViewColumn.cs @@ -183,6 +183,15 @@ public double ActualWidth set => SetValue(ActualWidthProperty, value); } + /// + /// Gets or sets the ColumnAutoWidthMode of the column. + /// + public ColumnAutoWidthMode? ColumnAutoWidthMode + { + get => (ColumnAutoWidthMode?)GetValue(ColumnAutoWidthModeProperty); + set => SetValue(ColumnAutoWidthModeProperty, value); + } + /// /// Gets or sets a value indicating whether the column can be resized. /// @@ -504,6 +513,11 @@ public string? SortMemberPath /// public static readonly DependencyProperty ActualWidthProperty = DependencyProperty.Register(nameof(ActualWidth), typeof(double), typeof(TableViewColumn), new PropertyMetadata(0d, OnPropertyChanged)); + /// + /// Identifies the ActualWidth dependency property. + /// + public static readonly DependencyProperty ColumnAutoWidthModeProperty = DependencyProperty.Register(nameof(ColumnAutoWidthMode), typeof(ColumnAutoWidthMode?), typeof(TableViewColumn), new PropertyMetadata(null)); + /// /// Identifies the CanResize dependency property. /// diff --git a/src/TableView.Properties.cs b/src/TableView.Properties.cs index d90e7d26..d3c651cd 100644 --- a/src/TableView.Properties.cs +++ b/src/TableView.Properties.cs @@ -221,6 +221,11 @@ public partial class TableView /// public static readonly DependencyProperty RowHeaderTemplateSelectorProperty = DependencyProperty.Register(nameof(RowHeaderTemplateSelector), typeof(DataTemplateSelector), typeof(TableView), new PropertyMetadata(null, OnRowHeaderTemplateChanged)); + /// + /// Identifies the ColumnAutoWidthMode dependency property. + /// + public static readonly DependencyProperty ColumnAutoWidthModeProperty = DependencyProperty.Register(nameof(ColumnAutoWidthMode), typeof(ColumnAutoWidthMode), typeof(TableView), new PropertyMetadata(ColumnAutoWidthMode.Cells)); + /// /// Identifies the FrozenColumnCount dependency property. /// @@ -725,6 +730,15 @@ public DataTemplateSelector RowHeaderTemplateSelector set => SetValue(RowHeaderTemplateSelectorProperty, value); } + /// + /// Gets or sets the ColumnAutoWidthMode for all columns. + /// + public ColumnAutoWidthMode ColumnAutoWidthMode + { + get => (ColumnAutoWidthMode)GetValue(ColumnAutoWidthModeProperty); + set => SetValue(ColumnAutoWidthModeProperty, value); + } + /// /// Gets or sets the number of columns that stays in view on horizontal scroll. /// diff --git a/src/TableViewCell.cs b/src/TableViewCell.cs index 758c3b14..9b3937b6 100644 --- a/src/TableViewCell.cs +++ b/src/TableViewCell.cs @@ -111,73 +111,77 @@ void OnContentLoaded(object sender, RoutedEventArgs e) /// protected override Size MeasureOverride(Size availableSize) { - if (Column is not null && Row is not null && _contentPresenter is not null && Content is FrameworkElement element) + if (TableView is not null && Column is not null && Row is not null && _contentPresenter is not null && Content is FrameworkElement element) { - if (Column is TableViewTemplateColumn) + var autoSizeMode = Column.ColumnAutoWidthMode ?? TableView.ColumnAutoWidthMode; + if (autoSizeMode is ColumnAutoWidthMode.Cells or ColumnAutoWidthMode.Both) { + if (Column is TableViewTemplateColumn) + { #if WINDOWS - if (element is ContentControl { ContentTemplateRoot: FrameworkElement root }) + if (element is ContentControl { ContentTemplateRoot: FrameworkElement root }) #else if (element.FindDescendant() is { ContentTemplateRoot: FrameworkElement root }) #endif - element = root; + element = root; + else + return base.MeasureOverride(availableSize); + } + + #region TEMP_FIX_FOR_ISSUE https://github.com/microsoft/microsoft-ui-xaml/issues/9860 + element.MaxWidth = double.PositiveInfinity; + element.MaxHeight = double.PositiveInfinity; + #endregion + + element.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); + + var desiredWidth = element.DesiredSize.Width; + desiredWidth += Padding.Left; + desiredWidth += Padding.Right; + desiredWidth += BorderThickness.Left; + desiredWidth += BorderThickness.Right; + desiredWidth += _selectionBorder?.BorderThickness.Right ?? 0; + desiredWidth += _selectionBorder?.BorderThickness.Left ?? 0; + desiredWidth += _v_gridLine?.ActualWidth ?? 0d; + + Column.DesiredWidth = Math.Max(Column.DesiredWidth, desiredWidth); + + #region TEMP_FIX_FOR_ISSUE https://github.com/microsoft/microsoft-ui-xaml/issues/9860 + var contentWidth = Column.ActualWidth; + contentWidth -= element.Margin.Left; + contentWidth -= element.Margin.Right; + contentWidth -= Padding.Left; + contentWidth -= Padding.Right; + contentWidth -= BorderThickness.Left; + contentWidth -= BorderThickness.Right; + contentWidth -= _selectionBorder?.BorderThickness.Left ?? 0; + contentWidth -= _selectionBorder?.BorderThickness.Right ?? 0; + contentWidth -= _v_gridLine?.ActualWidth ?? 0d; + + var height = Height is double.NaN ? double.PositiveInfinity : Height; + var contentHeight = Math.Min(height, MaxHeight); + contentHeight -= element.Margin.Top; + contentHeight -= element.Margin.Bottom; + contentHeight -= Padding.Top; + contentHeight -= Padding.Bottom; + contentHeight -= BorderThickness.Top; + contentHeight -= BorderThickness.Bottom; + contentHeight -= _selectionBorder?.BorderThickness.Top ?? 0; + contentHeight -= _selectionBorder?.BorderThickness.Bottom ?? 0; + contentHeight -= GetHorizontalGridlineHeight(); + + if (contentWidth < 0 || contentHeight < 0) + { + _contentPresenter.Visibility = Visibility.Collapsed; + } else - return base.MeasureOverride(availableSize); + { + element.MaxWidth = contentWidth; + element.MaxHeight = contentHeight; + _contentPresenter.Visibility = Visibility.Visible; + } + #endregion } - - #region TEMP_FIX_FOR_ISSUE https://github.com/microsoft/microsoft-ui-xaml/issues/9860 - element.MaxWidth = double.PositiveInfinity; - element.MaxHeight = double.PositiveInfinity; - #endregion - - element.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); - - var desiredWidth = element.DesiredSize.Width; - desiredWidth += Padding.Left; - desiredWidth += Padding.Right; - desiredWidth += BorderThickness.Left; - desiredWidth += BorderThickness.Right; - desiredWidth += _selectionBorder?.BorderThickness.Right ?? 0; - desiredWidth += _selectionBorder?.BorderThickness.Left ?? 0; - desiredWidth += _v_gridLine?.ActualWidth ?? 0d; - - Column.DesiredWidth = Math.Max(Column.DesiredWidth, desiredWidth); - - #region TEMP_FIX_FOR_ISSUE https://github.com/microsoft/microsoft-ui-xaml/issues/9860 - var contentWidth = Column.ActualWidth; - contentWidth -= element.Margin.Left; - contentWidth -= element.Margin.Right; - contentWidth -= Padding.Left; - contentWidth -= Padding.Right; - contentWidth -= BorderThickness.Left; - contentWidth -= BorderThickness.Right; - contentWidth -= _selectionBorder?.BorderThickness.Left ?? 0; - contentWidth -= _selectionBorder?.BorderThickness.Right ?? 0; - contentWidth -= _v_gridLine?.ActualWidth ?? 0d; - - var height = Height is double.NaN ? double.PositiveInfinity : Height; - var contentHeight = Math.Min(height, MaxHeight); - contentHeight -= element.Margin.Top; - contentHeight -= element.Margin.Bottom; - contentHeight -= Padding.Top; - contentHeight -= Padding.Bottom; - contentHeight -= BorderThickness.Top; - contentHeight -= BorderThickness.Bottom; - contentHeight -= _selectionBorder?.BorderThickness.Top ?? 0; - contentHeight -= _selectionBorder?.BorderThickness.Bottom ?? 0; - contentHeight -= GetHorizontalGridlineHeight(); - - if (contentWidth < 0 || contentHeight < 0) - { - _contentPresenter.Visibility = Visibility.Collapsed; - } - else - { - element.MaxWidth = contentWidth; - element.MaxHeight = contentHeight; - _contentPresenter.Visibility = Visibility.Visible; - } - #endregion } return base.MeasureOverride(availableSize); diff --git a/src/TableViewColumnHeader.cs b/src/TableViewColumnHeader.cs index 8a0017fe..d5a7b57f 100644 --- a/src/TableViewColumnHeader.cs +++ b/src/TableViewColumnHeader.cs @@ -10,6 +10,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Windows.Foundation; using Windows.System; using Windows.UI.Core; using WinUI.TableView.Collections; @@ -597,6 +598,23 @@ protected override void OnPointerReleased(PointerRoutedEventArgs e) _reorderStarted = false; } + /// + protected override Size MeasureOverride(Size availableSize) + { + var desiredHeaderSize = base.MeasureOverride(availableSize); + + if (Column is not null && _tableView is not null) + { + var autoWidthMode = Column.ColumnAutoWidthMode ?? _tableView.ColumnAutoWidthMode; + if (autoWidthMode is ColumnAutoWidthMode.Header or ColumnAutoWidthMode.Both) + { + Column.DesiredWidth = Math.Max(Column.DesiredWidth, desiredHeaderSize.Width); + } + } + + return desiredHeaderSize; + } + /// /// Ensures grid lines are applied. /// From e05c563eb524442e1fbee23fa90f518a3dc1a5c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20Torsg=C3=A5rden?= Date: Wed, 13 May 2026 18:38:55 +0200 Subject: [PATCH 02/10] Adjust calculations --- src/TableViewCell.cs | 97 ++++++++++++++++++++++---------------------- 1 file changed, 49 insertions(+), 48 deletions(-) diff --git a/src/TableViewCell.cs b/src/TableViewCell.cs index 9b3937b6..8191dbaa 100644 --- a/src/TableViewCell.cs +++ b/src/TableViewCell.cs @@ -114,27 +114,28 @@ protected override Size MeasureOverride(Size availableSize) if (TableView is not null && Column is not null && Row is not null && _contentPresenter is not null && Content is FrameworkElement element) { var autoSizeMode = Column.ColumnAutoWidthMode ?? TableView.ColumnAutoWidthMode; - if (autoSizeMode is ColumnAutoWidthMode.Cells or ColumnAutoWidthMode.Both) + + if (Column is TableViewTemplateColumn) { - if (Column is TableViewTemplateColumn) - { #if WINDOWS - if (element is ContentControl { ContentTemplateRoot: FrameworkElement root }) + if (element is ContentControl { ContentTemplateRoot: FrameworkElement root }) #else if (element.FindDescendant() is { ContentTemplateRoot: FrameworkElement root }) #endif - element = root; - else - return base.MeasureOverride(availableSize); - } + element = root; + else + return base.MeasureOverride(availableSize); + } - #region TEMP_FIX_FOR_ISSUE https://github.com/microsoft/microsoft-ui-xaml/issues/9860 - element.MaxWidth = double.PositiveInfinity; - element.MaxHeight = double.PositiveInfinity; - #endregion + #region TEMP_FIX_FOR_ISSUE https://github.com/microsoft/microsoft-ui-xaml/issues/9860 + element.MaxWidth = double.PositiveInfinity; + element.MaxHeight = double.PositiveInfinity; + #endregion - element.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); + element.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); + if (autoSizeMode is ColumnAutoWidthMode.Cells or ColumnAutoWidthMode.Both) + { var desiredWidth = element.DesiredSize.Width; desiredWidth += Padding.Left; desiredWidth += Padding.Right; @@ -145,43 +146,43 @@ protected override Size MeasureOverride(Size availableSize) desiredWidth += _v_gridLine?.ActualWidth ?? 0d; Column.DesiredWidth = Math.Max(Column.DesiredWidth, desiredWidth); + } - #region TEMP_FIX_FOR_ISSUE https://github.com/microsoft/microsoft-ui-xaml/issues/9860 - var contentWidth = Column.ActualWidth; - contentWidth -= element.Margin.Left; - contentWidth -= element.Margin.Right; - contentWidth -= Padding.Left; - contentWidth -= Padding.Right; - contentWidth -= BorderThickness.Left; - contentWidth -= BorderThickness.Right; - contentWidth -= _selectionBorder?.BorderThickness.Left ?? 0; - contentWidth -= _selectionBorder?.BorderThickness.Right ?? 0; - contentWidth -= _v_gridLine?.ActualWidth ?? 0d; - - var height = Height is double.NaN ? double.PositiveInfinity : Height; - var contentHeight = Math.Min(height, MaxHeight); - contentHeight -= element.Margin.Top; - contentHeight -= element.Margin.Bottom; - contentHeight -= Padding.Top; - contentHeight -= Padding.Bottom; - contentHeight -= BorderThickness.Top; - contentHeight -= BorderThickness.Bottom; - contentHeight -= _selectionBorder?.BorderThickness.Top ?? 0; - contentHeight -= _selectionBorder?.BorderThickness.Bottom ?? 0; - contentHeight -= GetHorizontalGridlineHeight(); - - if (contentWidth < 0 || contentHeight < 0) - { - _contentPresenter.Visibility = Visibility.Collapsed; - } - else - { - element.MaxWidth = contentWidth; - element.MaxHeight = contentHeight; - _contentPresenter.Visibility = Visibility.Visible; - } - #endregion + #region TEMP_FIX_FOR_ISSUE https://github.com/microsoft/microsoft-ui-xaml/issues/9860 + var contentWidth = Column.ActualWidth; + contentWidth -= element.Margin.Left; + contentWidth -= element.Margin.Right; + contentWidth -= Padding.Left; + contentWidth -= Padding.Right; + contentWidth -= BorderThickness.Left; + contentWidth -= BorderThickness.Right; + contentWidth -= _selectionBorder?.BorderThickness.Left ?? 0; + contentWidth -= _selectionBorder?.BorderThickness.Right ?? 0; + contentWidth -= _v_gridLine?.ActualWidth ?? 0d; + + var height = Height is double.NaN ? double.PositiveInfinity : Height; + var contentHeight = Math.Min(height, MaxHeight); + contentHeight -= element.Margin.Top; + contentHeight -= element.Margin.Bottom; + contentHeight -= Padding.Top; + contentHeight -= Padding.Bottom; + contentHeight -= BorderThickness.Top; + contentHeight -= BorderThickness.Bottom; + contentHeight -= _selectionBorder?.BorderThickness.Top ?? 0; + contentHeight -= _selectionBorder?.BorderThickness.Bottom ?? 0; + contentHeight -= GetHorizontalGridlineHeight(); + + if (contentWidth < 0 || contentHeight < 0) + { + _contentPresenter.Visibility = Visibility.Collapsed; + } + else + { + element.MaxWidth = contentWidth; + element.MaxHeight = contentHeight; + _contentPresenter.Visibility = Visibility.Visible; } + #endregion } return base.MeasureOverride(availableSize); From 6f97d64ef02d003f2457acbc1d715a85c143c754 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20Torsg=C3=A5rden?= Date: Wed, 13 May 2026 18:39:58 +0200 Subject: [PATCH 03/10] Move code --- src/TableViewCell.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/TableViewCell.cs b/src/TableViewCell.cs index 8191dbaa..2080033f 100644 --- a/src/TableViewCell.cs +++ b/src/TableViewCell.cs @@ -113,8 +113,6 @@ protected override Size MeasureOverride(Size availableSize) { if (TableView is not null && Column is not null && Row is not null && _contentPresenter is not null && Content is FrameworkElement element) { - var autoSizeMode = Column.ColumnAutoWidthMode ?? TableView.ColumnAutoWidthMode; - if (Column is TableViewTemplateColumn) { #if WINDOWS @@ -134,6 +132,7 @@ protected override Size MeasureOverride(Size availableSize) element.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); + var autoSizeMode = Column.ColumnAutoWidthMode ?? TableView.ColumnAutoWidthMode; if (autoSizeMode is ColumnAutoWidthMode.Cells or ColumnAutoWidthMode.Both) { var desiredWidth = element.DesiredSize.Width; From 7b7a333dd4ac2c9b9c3c6780b94cb143f113c794 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20Torsg=C3=A5rden?= Date: Tue, 19 May 2026 20:08:20 +0200 Subject: [PATCH 04/10] Adjust default and header width calculation --- src/TableView.Properties.cs | 2 +- src/TableViewHeaderRow.cs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/TableView.Properties.cs b/src/TableView.Properties.cs index d3c651cd..c58c62d7 100644 --- a/src/TableView.Properties.cs +++ b/src/TableView.Properties.cs @@ -224,7 +224,7 @@ public partial class TableView /// /// Identifies the ColumnAutoWidthMode dependency property. /// - public static readonly DependencyProperty ColumnAutoWidthModeProperty = DependencyProperty.Register(nameof(ColumnAutoWidthMode), typeof(ColumnAutoWidthMode), typeof(TableView), new PropertyMetadata(ColumnAutoWidthMode.Cells)); + public static readonly DependencyProperty ColumnAutoWidthModeProperty = DependencyProperty.Register(nameof(ColumnAutoWidthMode), typeof(ColumnAutoWidthMode), typeof(TableView), new PropertyMetadata(ColumnAutoWidthMode.Both)); /// /// Identifies the FrozenColumnCount dependency property. diff --git a/src/TableViewHeaderRow.cs b/src/TableViewHeaderRow.cs index 1224f92b..e5b776a6 100644 --- a/src/TableViewHeaderRow.cs +++ b/src/TableViewHeaderRow.cs @@ -289,7 +289,8 @@ internal void CalculateHeaderWidths() var starUnitWeight = starColumns.Select(x => x.Width.Value).Sum(); var fixedWidth = autoColumns.Select(x => { - if (x.HeaderControl is { } header) + var autoWidthMode = x.ColumnAutoWidthMode ?? TableView.ColumnAutoWidthMode; + if (x.HeaderControl is { } header && autoWidthMode is not ColumnAutoWidthMode.Cells) { header.Measure(new Size(double.PositiveInfinity, height)); return Math.Max(x.DesiredWidth, header.DesiredSize.Width); From 8d6d24aa15e91350e70e7fe4b031c2f8f272ab59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20Torsg=C3=A5rden?= Date: Wed, 27 May 2026 21:00:21 +0200 Subject: [PATCH 05/10] Add sample page --- .../MainPage.xaml.cs | 1 + .../Pages/ColumnSizingPage.xaml | 82 +++++++++++++++++++ .../Pages/ColumnSizingPage.xaml.cs | 20 +++++ 3 files changed, 103 insertions(+) create mode 100644 samples/WinUI.TableView.SampleApp/Pages/ColumnSizingPage.xaml create mode 100644 samples/WinUI.TableView.SampleApp/Pages/ColumnSizingPage.xaml.cs diff --git a/samples/WinUI.TableView.SampleApp/MainPage.xaml.cs b/samples/WinUI.TableView.SampleApp/MainPage.xaml.cs index ef811570..3924dbbb 100644 --- a/samples/WinUI.TableView.SampleApp/MainPage.xaml.cs +++ b/samples/WinUI.TableView.SampleApp/MainPage.xaml.cs @@ -115,6 +115,7 @@ private void OnNavigationSelectionChanged(NavigationView sender, NavigationViewS "Data Export" => typeof(ExportPage), "Large Dataset" => typeof(LargeDataPage), "Conditional Cell Styling" => typeof(ConditionalStylingPage), + "Column Sizing" => typeof(ColumnSizingPage), _ => typeof(BlankPage) }; diff --git a/samples/WinUI.TableView.SampleApp/Pages/ColumnSizingPage.xaml b/samples/WinUI.TableView.SampleApp/Pages/ColumnSizingPage.xaml new file mode 100644 index 00000000..921bd112 --- /dev/null +++ b/samples/WinUI.TableView.SampleApp/Pages/ColumnSizingPage.xaml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + 200 + + + + + * + + + + + Auto + + + + + + + + + + + + + diff --git a/samples/WinUI.TableView.SampleApp/Pages/ColumnSizingPage.xaml.cs b/samples/WinUI.TableView.SampleApp/Pages/ColumnSizingPage.xaml.cs new file mode 100644 index 00000000..acb908bd --- /dev/null +++ b/samples/WinUI.TableView.SampleApp/Pages/ColumnSizingPage.xaml.cs @@ -0,0 +1,20 @@ +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Controls; + +namespace WinUI.TableView.SampleApp.Pages; + +public sealed partial class ColumnSizingPage : Page +{ + public ColumnSizingPage() + { + InitializeComponent(); + + } + + private void OnDataContextChanged(FrameworkElement sender, DataContextChangedEventArgs args) + { + if (DataContext is not ExampleViewModel viewModel) return; + + viewModel.Items = new(ExampleViewModel.ItemsList.Take(20)); + } +} \ No newline at end of file From de2697abbc69776b50ebcdcea3fe964a07e28bf9 Mon Sep 17 00:00:00 2001 From: Waheed Ahmad Date: Thu, 25 Jun 2026 04:49:52 +0500 Subject: [PATCH 06/10] recalculate column widths when ColumnAutoWidthMode changes --- src/Columns/TableViewColumn.cs | 15 +++++++++++++-- src/TableView.Properties.cs | 13 ++++++++++++- src/TableView.cs | 32 ++++++++++++++++++++++++++++++++ src/TableViewColumnHeader.cs | 20 ++++++-------------- src/TableViewHeaderRow.cs | 32 ++++++++++++++++++++------------ 5 files changed, 83 insertions(+), 29 deletions(-) diff --git a/src/Columns/TableViewColumn.cs b/src/Columns/TableViewColumn.cs index 70f50fd5..c9747bbb 100644 --- a/src/Columns/TableViewColumn.cs +++ b/src/Columns/TableViewColumn.cs @@ -442,6 +442,17 @@ private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChan } } + /// + /// Handles changes to the ColumnAutoWidthMode property. + /// + private static void OnColumnAutoWidthModeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (d is TableViewColumn column) + { + column.TableView?.RefreshColumnsAutoWidth([column]); + } + } + /// /// Handles changes to the CanFilter property. /// @@ -514,9 +525,9 @@ public string? SortMemberPath public static readonly DependencyProperty ActualWidthProperty = DependencyProperty.Register(nameof(ActualWidth), typeof(double), typeof(TableViewColumn), new PropertyMetadata(0d, OnPropertyChanged)); /// - /// Identifies the ActualWidth dependency property. + /// Identifies the ColumnAutoWidthMode dependency property. /// - public static readonly DependencyProperty ColumnAutoWidthModeProperty = DependencyProperty.Register(nameof(ColumnAutoWidthMode), typeof(ColumnAutoWidthMode?), typeof(TableViewColumn), new PropertyMetadata(null)); + public static readonly DependencyProperty ColumnAutoWidthModeProperty = DependencyProperty.Register(nameof(ColumnAutoWidthMode), typeof(ColumnAutoWidthMode?), typeof(TableViewColumn), new PropertyMetadata(null, OnColumnAutoWidthModeChanged)); /// /// Identifies the CanResize dependency property. diff --git a/src/TableView.Properties.cs b/src/TableView.Properties.cs index c58c62d7..0a52fccd 100644 --- a/src/TableView.Properties.cs +++ b/src/TableView.Properties.cs @@ -224,7 +224,7 @@ public partial class TableView /// /// Identifies the ColumnAutoWidthMode dependency property. /// - public static readonly DependencyProperty ColumnAutoWidthModeProperty = DependencyProperty.Register(nameof(ColumnAutoWidthMode), typeof(ColumnAutoWidthMode), typeof(TableView), new PropertyMetadata(ColumnAutoWidthMode.Both)); + public static readonly DependencyProperty ColumnAutoWidthModeProperty = DependencyProperty.Register(nameof(ColumnAutoWidthMode), typeof(ColumnAutoWidthMode), typeof(TableView), new PropertyMetadata(ColumnAutoWidthMode.Both, OnColumnAutoWidthModeChanged)); /// /// Identifies the FrozenColumnCount dependency property. @@ -902,6 +902,17 @@ private static void OnCanFilterColumnsChanged(DependencyObject d, DependencyProp } } + /// + /// Handles changes to the ColumnAutoWidthMode property. + /// + private static void OnColumnAutoWidthModeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (d is TableView tableView) + { + tableView.RefreshColumnsAutoWidth(); + } + } + /// /// Handles changes to the MinColumnWidth property. /// diff --git a/src/TableView.cs b/src/TableView.cs index e21a6d3e..4a5973b4 100644 --- a/src/TableView.cs +++ b/src/TableView.cs @@ -1383,6 +1383,38 @@ internal void EnsureAlternateRowColors() }); } + /// + /// Resets the auto-calculated widths of the specified columns and recalculates them. + /// + /// The columns to refresh. When null, all columns are refreshed. + internal void RefreshColumnsAutoWidth(IEnumerable? columns = null) + { + var targetColumns = (columns ?? Columns).ToList(); + if (targetColumns.Count == 0) + { + return; + } + + foreach (var column in targetColumns) + { + column.DesiredWidth = 0d; + column.HeaderControl?.InvalidateMeasure(); + } + + foreach (var row in _rows) + { + foreach (var cell in row.Cells) + { + if (cell.Column is { } cellColumn && targetColumns.Contains(cellColumn)) + { + cell.InvalidateMeasure(); + } + } + } + + DispatcherQueue.TryEnqueue(() => _headerRow?.CalculateHeaderWidths()); + } + /// /// Ensures the column headers style is applied. /// diff --git a/src/TableViewColumnHeader.cs b/src/TableViewColumnHeader.cs index d5a7b57f..619119d0 100644 --- a/src/TableViewColumnHeader.cs +++ b/src/TableViewColumnHeader.cs @@ -10,6 +10,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using System.Xml.Linq; using Windows.Foundation; using Windows.System; using Windows.UI.Core; @@ -67,7 +68,7 @@ public TableViewColumnHeader() /// private void OnWidthChanged(DependencyObject sender, DependencyProperty dp) { - if (Column is not null) + if (Column is not null && !double.IsNaN(Width)) { Column.ActualWidth = Width; } @@ -463,19 +464,11 @@ protected override void OnDoubleTapped(DoubleTappedRoutedEventArgs e) if (position.X <= 8 && _headerRow?.GetPreviousHeader(this) is { Column: { } } header) { - var width = Math.Clamp( - header.Column.DesiredWidth, - header.Column.MinWidth ?? _tableView.MinColumnWidth, - header.Column.MaxWidth ?? _tableView.MaxColumnWidth); - header.Column.Width = new GridLength(width, GridUnitType.Pixel); + header.Column.Width = GridLength.Auto; } else if (Column is not null) { - var width = Math.Clamp( - Column.DesiredWidth, - Column.MinWidth ?? _tableView.MinColumnWidth, - Column.MaxWidth ?? _tableView.MaxColumnWidth); - Column.Width = new GridLength(width, GridUnitType.Pixel); + Column.Width = GridLength.Auto; } } @@ -601,18 +594,17 @@ protected override void OnPointerReleased(PointerRoutedEventArgs e) /// protected override Size MeasureOverride(Size availableSize) { - var desiredHeaderSize = base.MeasureOverride(availableSize); - if (Column is not null && _tableView is not null) { var autoWidthMode = Column.ColumnAutoWidthMode ?? _tableView.ColumnAutoWidthMode; if (autoWidthMode is ColumnAutoWidthMode.Header or ColumnAutoWidthMode.Both) { + var desiredHeaderSize = base.MeasureOverride(new Size(double.PositiveInfinity, double.PositiveInfinity)); Column.DesiredWidth = Math.Max(Column.DesiredWidth, desiredHeaderSize.Width); } } - return desiredHeaderSize; + return base.MeasureOverride(availableSize); } /// diff --git a/src/TableViewHeaderRow.cs b/src/TableViewHeaderRow.cs index e5b776a6..46f798e2 100644 --- a/src/TableViewHeaderRow.cs +++ b/src/TableViewHeaderRow.cs @@ -284,20 +284,10 @@ internal void CalculateHeaderWidths() var autoColumns = allColumns.Where(x => x.Width.IsAuto).ToList(); var absoluteColumns = allColumns.Where(x => x.Width.IsAbsolute).ToList(); - var height = ActualHeight; var availableWidth = TableView.ActualWidth - 32; var starUnitWeight = starColumns.Select(x => x.Width.Value).Sum(); - var fixedWidth = autoColumns.Select(x => - { - var autoWidthMode = x.ColumnAutoWidthMode ?? TableView.ColumnAutoWidthMode; - if (x.HeaderControl is { } header && autoWidthMode is not ColumnAutoWidthMode.Cells) - { - header.Measure(new Size(double.PositiveInfinity, height)); - return Math.Max(x.DesiredWidth, header.DesiredSize.Width); - } - return x.DesiredWidth; - }).Sum(); + var fixedWidth = autoColumns.Select(GetColumnDesiredWidth).Sum(); fixedWidth += absoluteColumns.Select(x => x.ActualWidth).Sum(); availableWidth -= fixedWidth; @@ -342,7 +332,7 @@ internal void CalculateHeaderWidths() var width = column.Width.IsStar ? starUnitWidth * column.Width.Value : column.Width.IsAbsolute ? column.Width.Value - : Math.Max(header.DesiredSize.Width, column.DesiredWidth); + : GetColumnDesiredWidth(column); var minWidth = column.MinWidth ?? TableView.MinColumnWidth; var maxWidth = column.MaxWidth ?? TableView.MaxColumnWidth; @@ -365,6 +355,24 @@ internal void CalculateHeaderWidths() } } + /// + /// Gets the desired width of a column based on its header and cells. + /// + private double GetColumnDesiredWidth(TableViewColumn column) + { + var autoWidthMode = column.ColumnAutoWidthMode ?? TableView?.ColumnAutoWidthMode; + var width = column.DesiredWidth; + + if (column.HeaderControl is { } header && autoWidthMode is not ColumnAutoWidthMode.Cells) + { + header.Width = double.NaN; + header.Measure(new Size(double.PositiveInfinity, ActualHeight)); + width = Math.Max(width, header.DesiredSize.Width); + } + + return width; + } + /// /// Sets the visibility of the export options. /// From 6f796b25d384cb895d614e2cdff8c6f3f70490c5 Mon Sep 17 00:00:00 2001 From: Waheed Ahmad Date: Thu, 25 Jun 2026 04:51:16 +0500 Subject: [PATCH 07/10] Rename ColumnAutoWidthMode to TableViewColumnAutoWidthMode --- src/Columns/TableViewColumn.cs | 6 +++--- src/TableView.Properties.cs | 6 +++--- src/TableViewCell.cs | 2 +- ...lumnAutoWidthMode.cs => TableViewColumnAutoWidthMode.cs} | 2 +- src/TableViewColumnHeader.cs | 2 +- src/TableViewHeaderRow.cs | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) rename src/{ColumnAutoWidthMode.cs => TableViewColumnAutoWidthMode.cs} (91%) diff --git a/src/Columns/TableViewColumn.cs b/src/Columns/TableViewColumn.cs index c9747bbb..b5b638f0 100644 --- a/src/Columns/TableViewColumn.cs +++ b/src/Columns/TableViewColumn.cs @@ -186,9 +186,9 @@ public double ActualWidth /// /// Gets or sets the ColumnAutoWidthMode of the column. /// - public ColumnAutoWidthMode? ColumnAutoWidthMode + public TableViewColumnAutoWidthMode? ColumnAutoWidthMode { - get => (ColumnAutoWidthMode?)GetValue(ColumnAutoWidthModeProperty); + get => (TableViewColumnAutoWidthMode?)GetValue(ColumnAutoWidthModeProperty); set => SetValue(ColumnAutoWidthModeProperty, value); } @@ -527,7 +527,7 @@ public string? SortMemberPath /// /// Identifies the ColumnAutoWidthMode dependency property. /// - public static readonly DependencyProperty ColumnAutoWidthModeProperty = DependencyProperty.Register(nameof(ColumnAutoWidthMode), typeof(ColumnAutoWidthMode?), typeof(TableViewColumn), new PropertyMetadata(null, OnColumnAutoWidthModeChanged)); + public static readonly DependencyProperty ColumnAutoWidthModeProperty = DependencyProperty.Register(nameof(ColumnAutoWidthMode), typeof(TableViewColumnAutoWidthMode?), typeof(TableViewColumn), new PropertyMetadata(null, OnColumnAutoWidthModeChanged)); /// /// Identifies the CanResize dependency property. diff --git a/src/TableView.Properties.cs b/src/TableView.Properties.cs index 0a52fccd..bbb35872 100644 --- a/src/TableView.Properties.cs +++ b/src/TableView.Properties.cs @@ -224,7 +224,7 @@ public partial class TableView /// /// Identifies the ColumnAutoWidthMode dependency property. /// - public static readonly DependencyProperty ColumnAutoWidthModeProperty = DependencyProperty.Register(nameof(ColumnAutoWidthMode), typeof(ColumnAutoWidthMode), typeof(TableView), new PropertyMetadata(ColumnAutoWidthMode.Both, OnColumnAutoWidthModeChanged)); + public static readonly DependencyProperty ColumnAutoWidthModeProperty = DependencyProperty.Register(nameof(ColumnAutoWidthMode), typeof(TableViewColumnAutoWidthMode), typeof(TableView), new PropertyMetadata(TableViewColumnAutoWidthMode.Both, OnColumnAutoWidthModeChanged)); /// /// Identifies the FrozenColumnCount dependency property. @@ -733,9 +733,9 @@ public DataTemplateSelector RowHeaderTemplateSelector /// /// Gets or sets the ColumnAutoWidthMode for all columns. /// - public ColumnAutoWidthMode ColumnAutoWidthMode + public TableViewColumnAutoWidthMode ColumnAutoWidthMode { - get => (ColumnAutoWidthMode)GetValue(ColumnAutoWidthModeProperty); + get => (TableViewColumnAutoWidthMode)GetValue(ColumnAutoWidthModeProperty); set => SetValue(ColumnAutoWidthModeProperty, value); } diff --git a/src/TableViewCell.cs b/src/TableViewCell.cs index 2080033f..ea8e1652 100644 --- a/src/TableViewCell.cs +++ b/src/TableViewCell.cs @@ -133,7 +133,7 @@ protected override Size MeasureOverride(Size availableSize) element.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); var autoSizeMode = Column.ColumnAutoWidthMode ?? TableView.ColumnAutoWidthMode; - if (autoSizeMode is ColumnAutoWidthMode.Cells or ColumnAutoWidthMode.Both) + if (autoSizeMode is TableViewColumnAutoWidthMode.Cells or TableViewColumnAutoWidthMode.Both) { var desiredWidth = element.DesiredSize.Width; desiredWidth += Padding.Left; diff --git a/src/ColumnAutoWidthMode.cs b/src/TableViewColumnAutoWidthMode.cs similarity index 91% rename from src/ColumnAutoWidthMode.cs rename to src/TableViewColumnAutoWidthMode.cs index e036a089..662c6bf8 100644 --- a/src/ColumnAutoWidthMode.cs +++ b/src/TableViewColumnAutoWidthMode.cs @@ -3,7 +3,7 @@ /// /// Specifies the behavior for automatic column width. /// -public enum ColumnAutoWidthMode +public enum TableViewColumnAutoWidthMode { /// /// Column width is adjusted to both header and maximum cell width. diff --git a/src/TableViewColumnHeader.cs b/src/TableViewColumnHeader.cs index 619119d0..b35180d1 100644 --- a/src/TableViewColumnHeader.cs +++ b/src/TableViewColumnHeader.cs @@ -597,7 +597,7 @@ protected override Size MeasureOverride(Size availableSize) if (Column is not null && _tableView is not null) { var autoWidthMode = Column.ColumnAutoWidthMode ?? _tableView.ColumnAutoWidthMode; - if (autoWidthMode is ColumnAutoWidthMode.Header or ColumnAutoWidthMode.Both) + if (autoWidthMode is TableViewColumnAutoWidthMode.Header or TableViewColumnAutoWidthMode.Both) { var desiredHeaderSize = base.MeasureOverride(new Size(double.PositiveInfinity, double.PositiveInfinity)); Column.DesiredWidth = Math.Max(Column.DesiredWidth, desiredHeaderSize.Width); diff --git a/src/TableViewHeaderRow.cs b/src/TableViewHeaderRow.cs index 46f798e2..350d8f63 100644 --- a/src/TableViewHeaderRow.cs +++ b/src/TableViewHeaderRow.cs @@ -363,7 +363,7 @@ private double GetColumnDesiredWidth(TableViewColumn column) var autoWidthMode = column.ColumnAutoWidthMode ?? TableView?.ColumnAutoWidthMode; var width = column.DesiredWidth; - if (column.HeaderControl is { } header && autoWidthMode is not ColumnAutoWidthMode.Cells) + if (column.HeaderControl is { } header && autoWidthMode is not TableViewColumnAutoWidthMode.Cells) { header.Width = double.NaN; header.Measure(new Size(double.PositiveInfinity, ActualHeight)); From 6d67cdac444ab3d31b8079512e185d3900ea0cdb Mon Sep 17 00:00:00 2001 From: Waheed Ahmad Date: Thu, 25 Jun 2026 04:57:35 +0500 Subject: [PATCH 08/10] Simplify ColumnSizingPage --- .../Pages/ColumnSizingPage.xaml | 75 +++++-------------- .../Pages/ColumnSizingPage.xaml.cs | 2 +- 2 files changed, 19 insertions(+), 58 deletions(-) diff --git a/samples/WinUI.TableView.SampleApp/Pages/ColumnSizingPage.xaml b/samples/WinUI.TableView.SampleApp/Pages/ColumnSizingPage.xaml index 921bd112..d9781e20 100644 --- a/samples/WinUI.TableView.SampleApp/Pages/ColumnSizingPage.xaml +++ b/samples/WinUI.TableView.SampleApp/Pages/ColumnSizingPage.xaml @@ -8,75 +8,36 @@ xmlns:tv="using:WinUI.TableView" xmlns:ui="using:CommunityToolkit.WinUI" d:DataContext="{d:DesignInstance Type=local:ExampleViewModel}" - mc:Ignorable="d"> + mc:Ignorable="d" + DataContextChanged="OnDataContextChanged"> - - - - - - - - - + ItemsSource="{Binding Items}" /> - - - - - 200 - - - - - * - - - - - Auto - - - - + - - - - + SelectedItem="{Binding ColumnAutoWidthMode, Mode=TwoWay, ElementName=tableView}" + ItemsSource="{ui:EnumValues Type=tv:TableViewColumnAutoWidthMode}" /> + + +<tv:TableView ItemsSource="{Binding Items}" + ColumnAutoWidthMode="$(ColumnAutoWidthMode)"/> + + + + + diff --git a/samples/WinUI.TableView.SampleApp/Pages/ColumnSizingPage.xaml.cs b/samples/WinUI.TableView.SampleApp/Pages/ColumnSizingPage.xaml.cs index acb908bd..8c60f26e 100644 --- a/samples/WinUI.TableView.SampleApp/Pages/ColumnSizingPage.xaml.cs +++ b/samples/WinUI.TableView.SampleApp/Pages/ColumnSizingPage.xaml.cs @@ -15,6 +15,6 @@ private void OnDataContextChanged(FrameworkElement sender, DataContextChangedEve { if (DataContext is not ExampleViewModel viewModel) return; - viewModel.Items = new(ExampleViewModel.ItemsList.Take(20)); + viewModel.Items = [.. ExampleViewModel.ItemsList.Take(20)]; } } \ No newline at end of file From 10371e74c3d0fa2957b95cfa7e22eaa504f50c09 Mon Sep 17 00:00:00 2001 From: Waheed Ahmad Date: Thu, 25 Jun 2026 15:45:57 +0500 Subject: [PATCH 09/10] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- samples/WinUI.TableView.SampleApp/Pages/ColumnSizingPage.xaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/WinUI.TableView.SampleApp/Pages/ColumnSizingPage.xaml b/samples/WinUI.TableView.SampleApp/Pages/ColumnSizingPage.xaml index d9781e20..48ee037e 100644 --- a/samples/WinUI.TableView.SampleApp/Pages/ColumnSizingPage.xaml +++ b/samples/WinUI.TableView.SampleApp/Pages/ColumnSizingPage.xaml @@ -12,7 +12,7 @@ DataContextChanged="OnDataContextChanged"> - Date: Thu, 25 Jun 2026 15:54:59 +0500 Subject: [PATCH 10/10] Potential fix for pull request finding --- src/TableView.cs | 2 +- src/TableViewColumnHeader.cs | 1 - src/TableViewHeaderRow.cs | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/TableView.cs b/src/TableView.cs index f372ae7f..1b504929 100644 --- a/src/TableView.cs +++ b/src/TableView.cs @@ -1873,7 +1873,7 @@ internal void EnsureAlternateRowColors() /// The columns to refresh. When null, all columns are refreshed. internal void RefreshColumnsAutoWidth(IEnumerable? columns = null) { - var targetColumns = (columns ?? Columns).ToList(); + var targetColumns = (columns ?? Columns).ToHashSet(); if (targetColumns.Count == 0) { return; diff --git a/src/TableViewColumnHeader.cs b/src/TableViewColumnHeader.cs index 88d50b76..996657d3 100644 --- a/src/TableViewColumnHeader.cs +++ b/src/TableViewColumnHeader.cs @@ -10,7 +10,6 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using System.Xml.Linq; using Windows.Foundation; using Windows.System; using Windows.UI.Core; diff --git a/src/TableViewHeaderRow.cs b/src/TableViewHeaderRow.cs index c636a154..d648b5a2 100644 --- a/src/TableViewHeaderRow.cs +++ b/src/TableViewHeaderRow.cs @@ -338,7 +338,6 @@ internal void CalculateHeaderWidths() width = width < minWidth ? minWidth : width; width = width > maxWidth ? maxWidth : width; header.Width = width; - header.MaxWidth = width; DispatcherQueue.TryEnqueue(() => header.Measure(