Description
Background and motivation
WPF has an infrastructure to present items in the UI through controls inheriting from ItemsControl
. These controls (such as ListBox
, DataGrid
etc.) work with a view over items, and the view supports sorting, grouping and filtering.
WPF also has an extensive system of commands including routing and binding, through which actions in applications are executed. Commands can be associated with input gestures to assign or change e.g. keyboard shortcuts to invoke these commands.
Finally, WPF did not originally ship with any controls that had UI to perform sorting, grouping and/or filtering of items. With the introduction of DataGrid
, users can now sort columns by clicking on their headers, however, no commands were added to support these user actions. As a result, developers cannot use the command system to introduce buttons to perform these operations or bind them to keyboard shortcuts.
We had a critical accessibility bug filed at one of the shipping WPF samples, stating that users cannot sort columns using keyboard. Having no commands for sorting has contributed to the unfortunate decision of hardcoding a keyboard shortcut in the framework itself, breaking customer applications without any way of mitigation, so a compatibility flag had to be introduced.
API Proposal
This PR proposes to add commands for manipulating view of items. Developers are free to use them for any operations, like sorting lines in a TextBox
.
namespace System.Windows.Input;
+ public static partial class ItemsCommands
+ {
+ public static System.Windows.Input.RoutedUICommand Sort { get; }
+ public static System.Windows.Input.RoutedUICommand Group { get; }
+ }
Furthermore, if DataGrid
implemented ItemsCommands.Sort
, the hardcoded behavior as well as the compatibility flag can be removed. For this, the following public API is proposed to be added:
namespace System.Windows.Controls;
public class DataGrid : System.Windows.Controls.Primitives.MultiSelector
{
...
+ protected virtual void OnCanExecuteSort(System.Windows.Input.CanExecuteRoutedEventArgs e);
+ protected virtual void OnExecutedSort(System.Windows.Input.ExecutedRoutedEventArgs e);
...
}
API Usage
To enable the WinForms behavior of sorting on F3, the developer would need to bind the command to the shortcut, e.g.:
<DataGrid>
<DataGrid.InputBindings>
<KeyBinding Gesture="F3" Command="Sort" />
</DataGrid.InputBindings>
</DataGrid>
Alternative Designs
This is a proposal to expand the existing set of built-in commands to cover operations on collection of items. There are no existing commands that could be reused for this purpose, and addressing the need using any other way would go against the philosophy of WPF.
At the moment only two commands are proposed that do not require any further input (i.e. when a cell is selected, it is clear what should happen when Sort or Group is involved). Depending on how urgent addressing the DataGrid
issue is, we can decide to ship with more events, including, but not limited to:
- Filter (UI would typically be needed to specify the filter by developers)
- reseting the view (removing all view sorting/grouping/filtering)
- sort ascending/descending (the
Sort
command is meant to toggle/cycle) - adding/removing to sort (
DataGrid
supports multiple sorted columns) - removing all grouping
- removing all filtering
These can be added anytime in the future, but I am happy to amend the proposal as per discussion.
Risks
I am not aware of any possibility of breaking changes (other than customer types inheriting from DataGrid
defining methods of the same name).
There is some supporting infrastructure to parse command names in XAML, getting command text etc. These would need to be amended to support the proposed ItemsCommands
on top of the existing ApplicationCommands
, NavigationCommands
, MediaCommands
and ComponentCommands
. The performance hit of doing so should be negligible (usually an extra if
).