Selector lacks invariant involving SelectedItem and SelectedItemsImpl
- Dominant language
- C#
- Stars
- 7.7k
- Forks
- 1.3k
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 61
Description
## Problem description
[`Selector`](https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.primitives.selector) publicly exposes `SelectedItem` ([documentation](https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.primitives.selector.selecteditem#System_Windows_Controls_Primitives_Selector_SelectedItem) and [source](https://github.com/dotnet/wpf/blob/826e2df1774c8beaf71d757d776a20b714b6dd5e/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Primitives/Selector.cs#L399)) and also has an [internal collection of selected items called `SelectedItemsImpl`](https://github.com/dotnet/wpf/blob/826e2df1774c8beaf71d757d776a20b714b6dd5e/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Primitives/Selector.cs#L803-L815) that are publicly exposed through `MultiSelector.SelectedItems` ([documentation](https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.primitives.multiselector.selecteditems#System_Windows_Controls_Primitives_MultiSelector_SelectedItems) and [source](https://github.com/dotnet/wpf/blob/826e2df1774c8beaf71d757d776a20b714b6dd5e/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Primitives/MultiSelector.cs#L36-L42)). Of course `SelectedItem` can't convey the same information when `SelectedItems` contains two or more items, but I think `SelectedItem` and the internal `SelectedItemsImpl` should be "as consistent as possible". Formally speaking, I think `Selector` should have the following class invariant.
```csharp
MyDataGrid.SelectedItems.Count switch {
0 => MyDataGrid.SelectedItem == null,
1 => MyDataGrid.SelectedItems[0] == MyDataGrid.SelectedItem,
_ => MyDataGrid.SelectedItems.Contains(MyDataGrid.SelectedItem)
}
```
However, that is not currently an invariant of `Selector`. Making this into an invariant of `Selector` would fix bug #4279.
## Steps to reproduce
My minimal reproduction is available at [TysonMN/SelectorLacksInvariant](https://github.com/TysonMN/SelectorLacksInvariant).
1. Run that reproduction
2. Click the `Button`
3. Observe the text "Yes", which indicates that the predicate of the invariant is currently `true`.
4. Click the only cell in the only row and column of the `DataGrid`.
5. Click the `Button`
Here are some additional details in case they matter.
* .NET Core Version:
- Version: 5.0.201
- Commit: a09bd5c86c
* Windows version: 1909 (OS Build 18363.1440)
* Does the bug reproduce also in WPF for .NET Framework 4.8?: Yes
## Expected behavior
The text "Yes" continues to be displayed just as observed in step 3.

## Actual behavior
The text "Yes" is replaced with "No", which indicates that the predicate of the invariant is currently `false`.

Contributor guide
Assessment
This issue has not been assessed yet.