dotnet / dotnet/wpf

Selector lacks invariant involving SelectedItem and SelectedItemsImpl

Open
#4,337 1 comment 2 reactions 0 assignees View on GitHub
Investigate
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.

![2021-03-27_20-41-54_590](https://user-images.githubusercontent.com/34664007/112739793-e94ed700-8f3c-11eb-8631-4b4596f9b062.gif)

## Actual behavior

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

![2021-03-27_20-22-41_585](https://user-images.githubusercontent.com/34664007/112739758-83fae600-8f3c-11eb-9463-f57e7ae58dbe.gif)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.