Skip to content

Commit d4b7b25

Browse files
authored
Merge pull request #151 from w-ahmad/cell_selection
Cell selection
2 parents 971d940 + 0b5778a commit d4b7b25

File tree

4 files changed

+80
-81
lines changed

4 files changed

+80
-81
lines changed

src/EventArgs/TableViewCellSelectionChangedEvenArgs.cs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,27 @@ namespace WinUI.TableView;
66
/// <summary>
77
/// Provides data for the cell selection changed event.
88
/// </summary>
9-
internal class TableViewCellSelectionChangedEvenArgs : EventArgs
9+
public class TableViewCellSelectionChangedEventArgs : EventArgs
1010
{
1111
/// <summary>
12-
/// Initializes a new instance of the TableViewCellSelectionChangedEvenArgs class.
12+
/// Initializes a new instance of the TableViewCellSelectionChangedEventArgs class.
1313
/// </summary>
14-
/// <param name="oldSelection">The old selection of cells.</param>
15-
/// <param name="newSelection">The new selection of cells.</param>
16-
public TableViewCellSelectionChangedEvenArgs(HashSet<TableViewCellSlot> oldSelection,
17-
HashSet<TableViewCellSlot> newSelection)
14+
/// <param name="removedCells">The list that contains the cells that were unselected.</param>
15+
/// <param name="addedCells">The list that contains the cells that were selected.</param>
16+
public TableViewCellSelectionChangedEventArgs(IList<TableViewCellSlot> removedCells,
17+
IList<TableViewCellSlot> addedCells)
1818
{
19-
OldSelection = oldSelection;
20-
NewSelection = newSelection;
19+
RemovedCells = removedCells;
20+
AddedCells = addedCells;
2121
}
2222

2323
/// <summary>
24-
/// Gets the old selection of cells.
24+
/// Gets a list that contains the cells that were unselected.
2525
/// </summary>
26-
public HashSet<TableViewCellSlot> OldSelection { get; }
26+
public IList<TableViewCellSlot> RemovedCells { get; }
2727

2828
/// <summary>
29-
/// Gets the new selection of cells.
29+
/// Gets a list that contains the cells that were selected.
3030
/// </summary>
31-
public HashSet<TableViewCellSlot> NewSelection { get; }
31+
public IList<TableViewCellSlot> AddedCells { get; }
3232
}

src/EventArgs/TableViewCurrentCellChangedEventArgs.cs

Lines changed: 0 additions & 30 deletions
This file was deleted.

src/TableView.Properties.cs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,11 @@ public partial class TableView
155155
/// Identifies the CellStyle dependency property.
156156
/// </summary>
157157
public static readonly DependencyProperty CellStyleProperty = DependencyProperty.Register(nameof(CellStyle), typeof(Style), typeof(TableView), new PropertyMetadata(null, OnCellStyleChanged));
158+
159+
/// <summary>
160+
/// Identifies the CurrentCellSlot dependency property.
161+
/// </summary>
162+
public static readonly DependencyProperty CurrentCellSlotProperty = DependencyProperty.Register(nameof(CurrentCellSlot), typeof(TableViewCellSlot?), typeof(TableView), new PropertyMetadata(default, OnCurrentCellSlotChanged));
158163

159164
/// <summary>
160165
/// Gets the collection view associated with the TableView.
@@ -177,9 +182,13 @@ public partial class TableView
177182
internal TableViewSelectionUnit LastSelectionUnit { get; set; }
178183

179184
/// <summary>
180-
/// Gets or sets the current cell slot.
185+
/// Gets or sets the current cell slot associated with the table view.
181186
/// </summary>
182-
internal TableViewCellSlot? CurrentCellSlot { get; set; }
187+
public TableViewCellSlot? CurrentCellSlot
188+
{
189+
get => (TableViewCellSlot?)GetValue(CurrentCellSlotProperty);
190+
set => SetValue(CurrentCellSlotProperty, value);
191+
}
183192

184193
/// <summary>
185194
/// Gets or sets the selection start cell slot.
@@ -579,7 +588,7 @@ private static void OnIsReadOnlyChanged(DependencyObject d, DependencyPropertyCh
579588
|| tableView.SelectionUnit is TableViewSelectionUnit.Row)
580589
&& tableView.IsReadOnly)
581590
{
582-
tableView.SetCurrentCell(null);
591+
tableView.CurrentCellSlot = null;
583592
}
584593
}
585594
}
@@ -682,6 +691,18 @@ private static void OnCellStyleChanged(DependencyObject d, DependencyPropertyCha
682691
}
683692
}
684693

694+
private static async void OnCurrentCellSlotChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
695+
{
696+
if (d is not TableView tableView) return;
697+
698+
tableView.CurrentCellChanged?.Invoke(d, e);
699+
700+
var oldSlot = e.OldValue as TableViewCellSlot?;
701+
var newSlot = e.NewValue as TableViewCellSlot?;
702+
703+
await tableView.OnCurrentCellChanged(oldSlot, newSlot);
704+
}
705+
685706
/// <summary>
686707
/// Throws an exception if the base ItemsSource property is set directly.
687708
/// </summary>

src/TableView.cs

Lines changed: 44 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ private void TableView_SelectionChanged(object sender, SelectionChangedEventArgs
7575
});
7676
}
7777

78-
SetCurrentCell(null);
78+
CurrentCellSlot = null;
7979
OnCellSelectionChanged();
8080

8181
if (SelectedIndex > 0)
@@ -192,7 +192,7 @@ private void HandleNavigations(KeyRoutedEventArgs e, bool shiftKey, bool ctrlKey
192192
if (isEditing && currentCell is not null)
193193
{
194194
currentCell = GetCellFromSlot(newSlot);
195-
currentCell.PrepareForEdit();
195+
currentCell?.PrepareForEdit();
196196
}
197197

198198
e.Handled = true;
@@ -803,7 +803,7 @@ public void RefreshFilter()
803803
if (SelectionUnit is TableViewSelectionUnit.Cell)
804804
{
805805
SelectAllCells();
806-
SetCurrentCell(null);
806+
CurrentCellSlot = null;
807807
}
808808
else
809809
{
@@ -886,7 +886,7 @@ private void DeselectAllCells()
886886
{
887887
SelectedCellRanges.Clear();
888888
OnCellSelectionChanged();
889-
SetCurrentCell(null);
889+
CurrentCellSlot = null;
890890
}
891891

892892
/// <summary>
@@ -922,17 +922,17 @@ internal void MakeSelection(TableViewCellSlot slot, bool shiftKey, bool ctrlKey
922922
{
923923
SelectRows(slot, shiftKey);
924924
LastSelectionUnit = TableViewSelectionUnit.Row;
925-
}
926-
else
927-
{
925+
}
926+
else
927+
{
928928
SelectCells(slot, shiftKey);
929929
LastSelectionUnit = TableViewSelectionUnit.Cell;
930930
}
931931
}
932932
else if (!IsReadOnly)
933933
{
934934
SelectionStartCellSlot = slot;
935-
DispatcherQueue.TryEnqueue(() => SetCurrentCell(slot));
935+
CurrentCellSlot = slot;
936936
}
937937
}
938938

@@ -948,14 +948,14 @@ private void SelectRows(TableViewCellSlot slot, bool shiftKey)
948948
if (selectionRange is not null)
949949
{
950950
DeselectRange(selectionRange);
951-
}
951+
}
952952

953953
if (shiftKey && SelectionMode is ListViewSelectionMode.Multiple or ListViewSelectionMode.Extended)
954954
{
955955
var min = Math.Min(SelectionStartRowIndex.Value, slot.Row);
956956
var max = Math.Max(SelectionStartRowIndex.Value, slot.Row);
957957

958-
SelectRange(new ItemIndexRange(min, (uint)(max - min) + 1));
958+
SelectRange(new ItemIndexRange(min, (uint)(max - min) + 1));
959959
}
960960
else
961961
{
@@ -968,11 +968,11 @@ private void SelectRows(TableViewCellSlot slot, bool shiftKey)
968968
{
969969
SelectRange(new ItemIndexRange(slot.Row, 1));
970970
}
971-
}
971+
}
972972

973973
if (!IsReadOnly && slot.IsValid(this))
974974
{
975-
DispatcherQueue.TryEnqueue(() => SetCurrentCell(slot));
975+
CurrentCellSlot = slot;
976976
}
977977
else
978978
{
@@ -1033,7 +1033,7 @@ private void SelectCells(TableViewCellSlot slot, bool shiftKey)
10331033

10341034
SelectedCellRanges.Add(selectionRange);
10351035
OnCellSelectionChanged();
1036-
DispatcherQueue.TryEnqueue(() => SetCurrentCell(slot));
1036+
CurrentCellSlot = slot;
10371037
}
10381038

10391039
/// <summary>
@@ -1049,38 +1049,32 @@ internal void DeselectCell(TableViewCellSlot slot)
10491049
SelectedCellRanges.Remove(selectionRange);
10501050
}
10511051

1052-
SetCurrentCell(slot);
1052+
CurrentCellSlot = slot;
10531053
OnCellSelectionChanged();
10541054
}
10551055

10561056
/// <summary>
1057-
/// Sets the current cell based on the specified cell slot.
1057+
/// Handles changes to the current cell in the table view.
10581058
/// </summary>
1059-
internal async void SetCurrentCell(TableViewCellSlot? slot)
1059+
private async Task OnCurrentCellChanged(TableViewCellSlot? oldSlot, TableViewCellSlot? newSlot)
10601060
{
1061-
if (slot == CurrentCellSlot)
1061+
if (oldSlot == newSlot)
10621062
{
10631063
return;
10641064
}
10651065

1066-
var oldSlot = CurrentCellSlot;
1067-
var currentCell = oldSlot.HasValue ? GetCellFromSlot(oldSlot.Value) : default;
1068-
currentCell?.SetElement();
1069-
CurrentCellSlot = slot;
1070-
1071-
if (oldSlot is { })
1066+
if (oldSlot.HasValue)
10721067
{
1073-
var row = _rows.FirstOrDefault(x => x.Index == oldSlot.Value.Row);
1074-
row?.ApplyCurrentCellState(oldSlot.Value);
1068+
var cell = GetCellFromSlot(oldSlot.Value);
1069+
cell?.SetElement();
1070+
cell?.ApplyCurrentCellState();
10751071
}
10761072

1077-
if (slot is { })
1073+
if (newSlot.HasValue)
10781074
{
1079-
var cell = await ScrollCellIntoView(slot.Value);
1075+
var cell = await ScrollCellIntoView(newSlot.Value);
10801076
cell?.ApplyCurrentCellState();
10811077
}
1082-
1083-
CurrentCellChanged?.Invoke(this, new TableViewCurrentCellChangedEventArgs(oldSlot, slot));
10841078
}
10851079

10861080
/// <summary>
@@ -1101,10 +1095,24 @@ private void OnCellSelectionChanged()
11011095
row?.ApplyCellsSelectionState();
11021096
}
11031097

1104-
SelectedCellsChanged?.Invoke(this, new TableViewCellSelectionChangedEvenArgs(oldSelection, SelectedCells));
1098+
InvokeCellSelectionChangedEvent(oldSelection);
11051099
});
11061100
}
11071101

1102+
/// <summary>
1103+
/// Invokes the <see cref="CellSelectionChanged"/> event to notify subscribers of changes in the selected cells.
1104+
/// </summary>
1105+
private void InvokeCellSelectionChangedEvent(HashSet<TableViewCellSlot> oldSelection)
1106+
{
1107+
var removedCells = oldSelection.Except(SelectedCells).ToList();
1108+
var addedCells = SelectedCells.Except(oldSelection).ToList();
1109+
1110+
if (removedCells.Count > 0 || addedCells.Count > 0)
1111+
{
1112+
CellSelectionChanged?.Invoke(this, new TableViewCellSelectionChangedEventArgs(removedCells, addedCells));
1113+
}
1114+
}
1115+
11081116
/// <summary>
11091117
/// Scrolls the specified cell slot into view.
11101118
/// </summary>
@@ -1227,9 +1235,9 @@ void ViewChanged(object? _, ScrollViewerViewChangedEventArgs e)
12271235
/// <summary>
12281236
/// Gets the cell based on the specified cell slot.
12291237
/// </summary>
1230-
internal TableViewCell GetCellFromSlot(TableViewCellSlot slot)
1238+
internal TableViewCell? GetCellFromSlot(TableViewCellSlot slot)
12311239
{
1232-
return slot.IsValid(this) && ContainerFromIndex(slot.Row) is TableViewRow row ? row.Cells[slot.Column] : default!;
1240+
return slot.IsValid(this) && ContainerFromIndex(slot.Row) is TableViewRow row ? row.Cells[slot.Column] : default;
12331241
}
12341242

12351243
/// <summary>
@@ -1475,12 +1483,12 @@ public virtual void OnClearSorting(TableViewClearSortingEventArgs eventArgs)
14751483
public event EventHandler<TableViewClearSortingEventArgs>? ClearSorting;
14761484

14771485
/// <summary>
1478-
/// Internal event triggered when selected cells change.
1486+
/// Event triggered when selected cells change.
14791487
/// </summary>
1480-
internal event EventHandler<TableViewCellSelectionChangedEvenArgs>? SelectedCellsChanged;
1488+
public event EventHandler<TableViewCellSelectionChangedEventArgs>? CellSelectionChanged;
14811489

14821490
/// <summary>
1483-
/// Internal event triggered when the current cell changes.
1491+
/// Event triggered when the current cell changes.
14841492
/// </summary>
1485-
internal event EventHandler<TableViewCurrentCellChangedEventArgs>? CurrentCellChanged;
1493+
public event DependencyPropertyChangedEventHandler? CurrentCellChanged;
14861494
}

0 commit comments

Comments
 (0)