dotnet / dotnet/winforms

DataGridView TopLeftHeaderCell visibility related problems

Open
#8,535 6 comments 1 reaction 0 assignees View on GitHub
area-controls-DataGridView
Dominant language
C#
Stars
4.9k
Forks
1.1k
Avg merge
20h 23m
Merged PRs (30d)
103

Description

### .NET version

All

### Did it work in .NET Framework?

No

### Did it work in any of the earlier releases of .NET Core or .NET 5+?

No

### Issue description

Comes from https://github.com/dotnet/winforms/issues/6926#issuecomment-1236143035 and related discussion. _Sorry had no time to raised it in time and then completely forgot about it_ 😔

- As far as I can tell, **all** `DataGridView` [Flaky tests](https://github.com/dotnet/winforms/issues/7799) have the same root. The `TopLeftHeaderCell` is not visible if we have no columns at all, but `DataGridView` still treat it as visible (still trying to Invalidate it) :(
- Also we have another non consistent behavior here -`DataGridView` without columns (left) look different from `DataGridView` with all invisible columns (right):
![image](https://user-images.githubusercontent.com/17767561/188275713-67683082-9c15-4050-a8b8-892c16004f83.png)
If we have no columns at all `TopLeftHeaderCell` not visible and if we have columns but they all set as not visible, `TopLeftHeaderCell` is visible 🤔 Also we have third variant [bound `DataGridView` with all invisible columns](https://github.com/dotnet/winforms/issues/4807) 😫

- Another bunch of bugs related to visibility of `TopLeftHeaderCell`. In many places it's checked like `DataGridView.LayoutInfo.TopLeftHeader != Rectangle.Empty`. And `DataGridView.LayoutInfo.TopLeftHeader` updated only in `PerformLayoutPrivate`. Which is not always called when necessary. For example if we have `DataGridView` with `AutoSize == true` and call `ColumnHeadersVisible = false` then we will get `TopLeftHeaderCell.Visible == false` and `TopLeftHeaderCell.Displayed == true` because `PerformLayoutPrivate` will not be called if `AutoSize == true` 😕

It seems that the option of the absence of columns was not considered in the context of `TopLeftHeaderCell`. I see 2 ways here:
1. Treat `TopLeftHeaderCell` invisible if we have no columns. This will be some how a [breaking change](https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.datagridviewheadercell.visible?f1url=%3FappId%3DDev16IDEF1%26l%3DEN-US%26k%3Dk(System.Windows.Forms.DataGridViewHeaderCell.Visible)%3Bk(SolutionItemsProject)%3Bk(DevLang-csharp)%26rd%3Dtrue&view=windowsdesktop-6.0#:~:text=If%20the%20cell%20is%20the%20top%20left%20header%20cell%2C%20it%20is%20visible%20if%20both%20RowHeadersVisible%20and%20ColumnHeadersVisible%20are%20true.)... And after that it will be necessary to redo about 60 tests that consider that `TopLeftHeaderCell` is always visible when `ColumnHeadersVisible` && `RowHeadersVisible`.
By the way, to fix all (I think) Flaky tests we no need to change `DataGridViewHeaderCell.Visible`, just add the conditions for invalidate in two places. Because all invalidated test are using empty (no columns) `DataGridView`. But if some one will add
tests with columns - we will get all this mouse problems again :(
2. Paint `TopLeftHeaderCell` in any cases if `ColumnHeadersVisible` && `RowHeadersVisible`. Will it be a _visual_ breaking change? This approach will not fix any of our flaky tests, but at least it will be clear what needs to be changed in them and why...

If we go with this I think we need to add tests which will put the mouse above `TopLeftHeaderCell`... So moving all _invalidated_ tests to UIIntegrationTests is something need to be done any way...

@RussKie [response](https://github.com/dotnet/winforms/issues/6926#issuecomment-1244876947) on this:

> Just to reiterate my understanding - we have a number of issues that we believe are all caused by the incorrect visibility handling of `TopLeftHeaderCell`. These issues are as follows (in no specific order):
>
> * multiple intermittent DGV-related test failures,
> * inconsistent behaviour depending on whether a DGV has any columns or not,
> * inconsistent behaviour depending on whether a DGV has any bound columns,
> * [DataGridView.TopLeftHeaderCell throws ArgumentOutOfRangeException on Handle creation #3378](https://github.com/dotnet/winforms/issues/3378)
> * [bound DataGridView with all invisible columns will display first column anyway #4807](https://github.com/dotnet/winforms/issues/4807)
>
> Did I get this correctly? 💭 What may be helpful here is a simple sample app - a form with a DGV and buttons - that show case different behaviours and deficiencies, so that we could observe different scenarios all in one place (like we did in [#3029 (comment)](https://github.com/dotnet/winforms/issues/3029#issuecomment-749295542)).
>
> All but the first issue (i.e., the test related) will require a hollistic review of the handling, and the fix will likely be breaking change; not to mention an extensive testing will be required. This path is not completely off the table, in fact with the [re-introduced support for feature switches](https://github.com/dotnet/winforms/blob/main/docs/WinformsRuntimeConfiguration.md) in .NET 7, we can consider fixing the behaviour putting it behind an opt-out switch (i.e., allow to return to the old behaviour). I don't think the team would be able to champion this work due to current and the already assigned priorities for the .NET 8 release. And we'd look up to the community to champion this (with the team's support, though limited).

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.