@@ -508,7 +508,7 @@ private void GenerateColumns()
508
508
var canFilter = displayAttribute ? . GetAutoGenerateFilter ( ) is true or null ;
509
509
var columnArgs = GenerateColumn ( propertyInfo . PropertyType , propertyInfo . Name , header , canFilter ) ;
510
510
OnAutoGeneratingColumn ( columnArgs ) ;
511
-
511
+
512
512
if ( ! columnArgs . Cancel && columnArgs . Column is not null )
513
513
{
514
514
columnArgs . Column . Order = displayAttribute ? . GetOrder ( ) ;
@@ -1132,31 +1132,39 @@ private void InvokeCellSelectionChangedEvent(HashSet<TableViewCellSlot> oldSelec
1132
1132
/// <param name="slot">The cell slot to scroll into view.</param>
1133
1133
public async Task < TableViewCell > ScrollCellIntoView ( TableViewCellSlot slot )
1134
1134
{
1135
- if ( _scrollViewer is null || ! slot . IsValid ( this ) ) return default ! ;
1135
+ if ( _scrollViewer is null || ! slot . IsValid ( this ) || await ScrollRowIntoView ( slot . Row ) is not { } row )
1136
+ return default ! ;
1136
1137
1137
- var row = await ScrollRowIntoView ( slot . Row ) ;
1138
1138
var ( start , end ) = GetColumnsInDisplay ( ) ;
1139
1139
var xOffset = 0d ;
1140
1140
var yOffset = _scrollViewer . VerticalOffset ;
1141
1141
1142
- if ( slot . Column < start )
1142
+ // Calculate the left and right edge of the cell
1143
+ var cellLeft = Columns . VisibleColumns . Take ( slot . Column ) . Sum ( x => x . ActualWidth ) ;
1144
+ var cellWidth = Columns . VisibleColumns [ slot . Column ] . ActualWidth ;
1145
+ var cellRight = cellLeft + cellWidth ;
1146
+ var viewportLeft = _scrollViewer . HorizontalOffset ;
1147
+ var viewportRight = viewportLeft + _scrollViewer . ViewportWidth - SelectionIndicatorWidth ;
1148
+
1149
+ // If cell is wider than the viewport, align left edge
1150
+ if ( cellWidth > _scrollViewer . ViewportWidth - SelectionIndicatorWidth )
1143
1151
{
1144
- for ( var i = 0 ; i < slot . Column ; i ++ )
1145
- {
1146
- xOffset += Columns . VisibleColumns [ i ] . ActualWidth ;
1147
- }
1152
+ xOffset = cellLeft ;
1148
1153
}
1149
- else if ( slot . Column > end )
1154
+ // If cell is left of the viewport, scroll to its left edge
1155
+ else if ( cellLeft < viewportLeft )
1150
1156
{
1151
- for ( var i = 0 ; i <= slot . Column ; i ++ )
1152
- {
1153
- xOffset += Columns . VisibleColumns [ i ] . ActualWidth ;
1154
- }
1155
-
1156
- var change = xOffset - _scrollViewer . HorizontalOffset - ( _scrollViewer . ViewportWidth - SelectionIndicatorWidth ) ;
1157
- xOffset = _scrollViewer . HorizontalOffset + change ;
1157
+ xOffset = cellLeft ;
1158
1158
}
1159
- else if ( row is not null )
1159
+ // If cell is right of the viewport, scroll so its right edge is visible
1160
+ else if ( cellRight > viewportRight )
1161
+ {
1162
+ xOffset = cellRight - ( _scrollViewer . ViewportWidth - SelectionIndicatorWidth ) ;
1163
+ }
1164
+
1165
+ // If cell is fully in view, just return
1166
+ if ( ( cellLeft >= viewportLeft && cellRight <= viewportRight ) ||
1167
+ xOffset == _scrollViewer . HorizontalOffset )
1160
1168
{
1161
1169
return row . Cells . ElementAt ( slot . Column ) ;
1162
1170
}
@@ -1176,8 +1184,7 @@ void ViewChanged(object? _, ScrollViewerViewChangedEventArgs e)
1176
1184
try
1177
1185
{
1178
1186
_scrollViewer . ViewChanged += ViewChanged ;
1179
- _scrollViewer . ChangeView ( xOffset , yOffset , null , true ) ;
1180
- _scrollViewer . ScrollToHorizontalOffset ( xOffset ) ;
1187
+ _scrollViewer . ChangeView ( xOffset , _scrollViewer . VerticalOffset , null , true ) ;
1181
1188
await tcs . Task ;
1182
1189
}
1183
1190
finally
@@ -1196,20 +1203,23 @@ void ViewChanged(object? _, ScrollViewerViewChangedEventArgs e)
1196
1203
{
1197
1204
if ( _scrollViewer is null ) return default ! ;
1198
1205
1206
+ var xOffset = _scrollViewer . HorizontalOffset ;
1199
1207
var item = Items [ index ] ;
1200
1208
index = Items . IndexOf ( item ) ; // if the ItemsSource has duplicate items in it. ScrollIntoView will only bring first index of item.
1201
1209
ScrollIntoView ( item ) ;
1202
1210
1203
1211
var tries = 0 ;
1204
1212
while ( tries < 10 )
1205
1213
{
1214
+ tries ++ ;
1215
+ await Task . Yield ( ) ;
1216
+
1206
1217
if ( ContainerFromIndex ( index ) is TableViewRow row )
1207
1218
{
1208
1219
var transform = row . TransformToVisual ( _scrollViewer ) ;
1209
1220
var positionInScrollViewer = transform . TransformPoint ( new Point ( 0 , 0 ) ) ;
1210
1221
if ( ( index == 0 && _scrollViewer . VerticalOffset > 0 ) || ( index > 0 && positionInScrollViewer . Y < HeaderRowHeight ) )
1211
1222
{
1212
- var xOffset = _scrollViewer . HorizontalOffset ;
1213
1223
var yOffset = index == 0 ? 0d : _scrollViewer . VerticalOffset - row . ActualHeight + positionInScrollViewer . Y + 8 ;
1214
1224
var tcs = new TaskCompletionSource < object ? > ( ) ;
1215
1225
@@ -1237,9 +1247,6 @@ void ViewChanged(object? _, ScrollViewerViewChangedEventArgs e)
1237
1247
1238
1248
return row ;
1239
1249
}
1240
-
1241
- tries ++ ;
1242
- await Task . Delay ( 1 ) ; // let the animation complete
1243
1250
}
1244
1251
1245
1252
return default ;
0 commit comments