Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/TableView.Properties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,11 @@
public static readonly DependencyProperty CanReorderColumnsProperty = DependencyProperty.Register(nameof(CanReorderColumns), typeof(bool), typeof(TableView), new PropertyMetadata(true));

/// <summary>
/// Identifies the UseListViewHotkeys dependency property.
/// </summary>
public static readonly DependencyProperty UseListViewHotkeysProperty = DependencyProperty.Register(nameof(UseListViewHotkeys), typeof(bool), typeof(TableView), new PropertyMetadata(false));
/// Identifies the <see cref="ConditionalCellStyles"/> dependency property.
/// </summary>

Check warning on line 263 in src/TableView.Properties.cs

View workflow job for this annotation

GitHub Actions / build

XML comment has badly formed XML -- 'End tag was not expected at this location.'

Check warning on line 263 in src/TableView.Properties.cs

View workflow job for this annotation

GitHub Actions / build

XML comment has badly formed XML -- 'End tag was not expected at this location.'

Check warning on line 263 in src/TableView.Properties.cs

View workflow job for this annotation

GitHub Actions / build

XML comment has badly formed XML -- 'End tag was not expected at this location.'

Check warning on line 263 in src/TableView.Properties.cs

View workflow job for this annotation

GitHub Actions / build

XML comment has badly formed XML -- 'End tag was not expected at this location.'
public static readonly DependencyProperty ConditionalCellStylesProperty = DependencyProperty.Register(nameof(ConditionalCellStyles), typeof(IList<TableViewConditionalCellStyle>), typeof(TableView), new PropertyMetadata(default));

/// <summary>
Expand Down Expand Up @@ -768,6 +771,15 @@
set => SetValue(CanReorderColumnsProperty, value);
}

/// <summary>
/// Gets or sets whether the TableView should use ListView like hotkeys for navigation and selection.
/// </summary>
public bool UseListViewHotkeys
{
get => (bool)GetValue(UseListViewHotkeysProperty);
set => SetValue(UseListViewHotkeysProperty, value);
}

/// <summary>
/// Handles changes to the ItemsSource property.
/// </summary>
Expand Down
121 changes: 121 additions & 0 deletions src/TableView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using System;
using System.Collections;
using System.Collections.Generic;
Expand Down Expand Up @@ -129,6 +130,13 @@ protected override DependencyObject GetContainerForItemOverride()
_rows.Add(row);
return row;
}

private bool IsRowKeyboardContext =>
(UseListViewHotkeys == true) && //Not sure if I'm solving a bug or adding a feature, so I've made it apply only when the UseListViewHotkeys is set to true just in case.
(SelectionUnit == TableViewSelectionUnit.Row ||
(SelectionUnit == TableViewSelectionUnit.CellOrRow &&
LastSelectionUnit == TableViewSelectionUnit.Row));


/// <inheritdoc/>
protected override async void OnKeyDown(KeyRoutedEventArgs e)
Expand All @@ -142,9 +150,94 @@ protected override async void OnKeyDown(KeyRoutedEventArgs e)
return;
}

if (!IsEditing && IsRowKeyboardContext)
{
if (!shiftKey &&
!ctrlKey &&
SelectionMode == ListViewSelectionMode.Multiple &&
e.Key == VirtualKey.Enter)
{
ToggleCurrentRowSelection();
e.Handled = true;
return;
}

var rowSelectionOnly = SelectionUnit == TableViewSelectionUnit.Row;

if (e.Key is VirtualKey.Up or VirtualKey.Down or
VirtualKey.Home or VirtualKey.End or
VirtualKey.PageUp or VirtualKey.PageDown ||
(rowSelectionOnly && (e.Key is VirtualKey.Left or VirtualKey.Right)))
{
int? prevCellRow = null;
if (SelectionUnit == TableViewSelectionUnit.Row && CurrentCellSlot.HasValue)
{
prevCellRow = CurrentCellSlot.Value.Row;
}

base.OnKeyDown(e); // Let ListView move the row focus / selection

var focusedIndex = GetFocusedRowIndex();
if (focusedIndex >= 0)
{
CurrentRowIndex = focusedIndex;
SelectionStartRowIndex ??= focusedIndex;
}

if (SelectionUnit == TableViewSelectionUnit.Row &&
prevCellRow.HasValue &&
focusedIndex >= 0 &&
focusedIndex != prevCellRow.Value)
{
CurrentCellSlot = null; // will un-apply old cell's current-state border
}
return;
}
}
// Everything else (cell nav, F2 in cell mode, Space, etc.)
await HandleNavigations(e, shiftKey, ctrlKey);
}



private void ToggleCurrentRowSelection()
{

var index = GetFocusedRowIndex();

if (index < 0)
{
var rowIndex = CurrentRowIndex ?? SelectedIndex;

if (rowIndex is < 0 || rowIndex >= Items.Count)
{
return;
}

index = rowIndex;
}


if (index < 0 || index >= Items.Count) { return; }

var isSelected = SelectedRanges.Any(r => r.IsInRange(index));

var singleIndexRange = new ItemIndexRange(index, 1u);

if (isSelected)
{
DeselectRange(singleIndexRange);
}
else
{
SelectRange(singleIndexRange);
}

SelectionStartRowIndex = index;
CurrentRowIndex = index;

}

/// <summary>
/// Handles navigation keys.
/// </summary>
Expand Down Expand Up @@ -385,6 +478,34 @@ private TableViewCellSlot GetNextSlot(TableViewCellSlot? currentSlot, bool isShi
return new TableViewCellSlot(nextRow, nextColumn);
}

private int GetFocusedRowIndex()
{
if (XamlRoot is null)
return -1;

var focused = FocusManager.GetFocusedElement(XamlRoot) as DependencyObject;
if (focused is null)
return -1;

var row = GetRowFromElement(focused);
return row?.Index ?? -1;
}

private static TableViewRow? GetRowFromElement(DependencyObject element)
{
var current = element;

while (current is not null)
{
if (current is TableViewRow row)
return row;

current = VisualTreeHelper.GetParent(current);
}

return null;
}

/// <summary>
/// Copies the selected rows or cells content to the clipboard.
/// </summary>
Expand Down
Loading