7

I just upgraded some systems to Windows 10 Creators Update and I noticed that the windows forms PropertyGrid control changed its default visual style for headers and bar margins to dark gray, like so:

<code>PropertyGrid</code> new style

And as mostly happens with unexpected visual changes, users are not happy. Is there a way to revert back to the old default or maybe override the default style?

glopes
  • 4,038
  • 3
  • 26
  • 29
  • 2
    It is the same color as PropertyGrid.LineColor. Given that it changed, you probably left it at its default setting, SystemColors.InactiveBorder. Microsoft does tinker with the system colors to make new versions of Windows look different. Or you selected the color scheme you preferred, hard to guess. Changing system colors has gotten a lot more difficult in later versions, [this superuser.com question](https://superuser.com/questions/949920/window-color-and-appearance-removed-in-win10) has details. The registry hack is the only useful one I imagine. – Hans Passant Apr 25 '17 at 13:50
  • 1
    On serveral machines here in my company, this is indeed caused by a Microsoft update. Tools running for several months now has a different style. Is there any place where one can finds changes done by updates? – joe Jun 28 '17 at 10:31
  • @joe: For .NET, they have release notes [here](https://github.com/Microsoft/dotnet/tree/master/releases), including links to known issues. – tm1 Jul 04 '17 at 06:11

3 Answers3

8

There's a bug in PropertyGrid:

The property PropertyGrid.LineColor has a DefaultValue attribute Set to SystemColors.InactiveBorder.
But the internal field lineColor is initialized with SystemColors.ControlDark.

This is bad, because the Windows Forms designer detects that the property has the same value as the DefaultValue attribute, and therefore it does not write the designer code for the PropertyGrid.LineColor property in InitializeComponent. So at runtime, the property is initialized to SystemColors.ControlDark.

As a quick hack, you can set the property after InitializeComponent:

InitializeComponent();
propertyGrid.LineColor = SystemColors.InactiveBorder;
joe
  • 8,344
  • 9
  • 54
  • 80
  • And as always, the `System.Windows.Forms` version deployed on the developer's computer specifies `SystemColors.InactiveBorder` for the `lineColor` field. – tm1 Jul 03 '17 at 09:38
  • You can vote for this through Visual Studio's "Report a Problem", typing `The LineColor of PropertyGrid is defined inconsistent`. The existing problem report indicates that the change was introduced with .NET 4.7. – tm1 Jul 03 '17 at 10:05
  • @tm1: Thanks, didn't know that you can report a bug directly through Visual Studio, thanks! – joe Jul 03 '17 at 18:47
3

We are reverting header color to InactiveBorder in the default windows theme in the next release of the .Net Framework, which most likely will be included in the Windows 10 Fall Creators Update. The reason this change was introduced, was that the foreground and background colors were not contrasting enough in one of the High Contrast themes, this is why we are reverting to the previously used color only in the default theme. For your reference, internal work item number, that will be also mentioned in release notes for .Net Framework 4.7.1, is 407249.

Thank you, Tanya

1

This seems to be a "feature". From the .NET Framework 4.7 Release Notes:

Changed the background color of property grid lines to provide an 8:1 contrast ratio for high contrast themes.

So, I'd say, no, with Windows 10 Creators Update, there's no way to revert to the old style without recompiling (see this answer).

I complained here.

Update

I refined the PropertyGrid class like this:

sealed class LightPropertyGrid : PropertyGrid {
    static readonly Color DefaultLineColor = (Color)
        typeof(PropertyGrid)
            .GetProperty(nameof(LineColor))
            .GetCustomAttribute<DefaultValueAttribute>()
            .Value;

    public LightPropertyGrid() {
        LineColor = DefaultLineColor;
    }
}

I'm inferring the initial value for LineColor from the default value defined on the same property. Of course, you can simply assign LineColor = SystemColors.InactiveBorder.

tm1
  • 1,180
  • 12
  • 28