¿Cómo cambiar el color del borde (o eliminar el borde) de un control PropertyGrid?

Having a standard WinForms 2.0 PropertyGrid Remoto I'm looking for a way to either change the border color of the control or remove the border altogether.

enter image description here

Soy consciente de la LineColor perfecta which unfortunately only changes the inner borders between the cells.

Additionally, I used ILSpy to take a look at the source code of the PropertyGrid control and still found nothing meaningful to me.

Mi pregunta es:

How to remove the outer border of a PropertyGrid control or change the color of the outer border?

Update 2012-05-04 - Solution (aka "hack"):

Basado en Jamie's answer I assembled a working solution (que puedes descargar desde aquí):

enter image description here

The idea is to place the property grid inside a panel and let the panel clip the control.

With this approach, I did place the clipping panel into another panel that has a Padding of "1" (or whatever you want the borders to be) and gave this panel a BackColor that serves as the border color (green in my example).

Set the Anchor of the property grid to "Left, Right, Top, Bottom", set the Dock of the clipping panel to "Full".

enter image description here

This works well for my requirements. I would see this as kind of a hack since it consumes the resources of two panels which I hoped I could save.

preguntado el 03 de mayo de 12 a las 10:05

5 Respuestas

this is another alternative, as it seems that my first answer is not suitable for this particular control. This is a dirty trick but should work:

Put a Panel control in your window or dialog, let say with size 100H x 300V. Put the propertygrid inside the panel with position -1,-1 and size 102,302.

contestado el 04 de mayo de 12 a las 09:05

Hehe, I already tried that in the past, unsuccessfully. I'll try it again once more, just in case I did something wrong. - Uwe Keim

@Jamie It worked, thanks for your suggestion! I'll update my question with your answer. - Uwe Keim

Be careful, this one can byte when the windows are resized because of automatic form scaling. You really want to write code in the panel's Resize event handler to always make sure the PropertyGrid is where it should be. - Hans Passant

Aquí está el código de mi proyecto

PropertyGrid have two controls that need process.
+ doccomment is Document help.
+ gridView that display property value.

Those controls draw border rectangle with color ControlDark.

We need re draw rectangle with HelpBackColor and LineColor to make clear view.

    namespace Bravo.Bravo7.UI
    {
        public class MyPropertyGrid : PropertyGrid
        {
            public class SnappableControl : NativeWindow
            {
                private Control _parent;
                private MyPropertyGrid _ownerGrid;

                public SnappableControl(Control parent, MyPropertyGrid ownerGrid)
                {
                    _parent = parent;
                    _parent.HandleCreated += _parent_HandleCreated;
                    _parent.HandleDestroyed += _owner_HandleDestroyed;

                    _ownerGrid = ownerGrid;
                }

                protected override void WndProc(ref Message m)
                {
                    base.WndProc(ref m);

                    switch (m.Msg)
                    {
                        case (int)NativeMethods.WM_NCPAINT:
                        case (int)NativeMethods.WM_PAINT:

                            using (var g = _parent.CreateGraphics())
                            {
                                using (var pen = new Pen(_ownerGrid.HelpBackColor))
                                {
                                    var clientRectangle = _parent.ClientRectangle;
                                    clientRectangle.Width--;
                                    clientRectangle.Height--;
                                    g.DrawRectangle(pen, clientRectangle);
                                }
                            }

                            break;
                    }
                }

                void _owner_HandleDestroyed(object sender, EventArgs e)
                {
                    ReleaseHandle();
                }

                void _parent_HandleCreated(object sender, EventArgs e)
                {
                    AssignHandle(_parent.Handle);
                }
            }

            public class PropertyGridView : NativeWindow
            {
                private Control _parent;
                private MyPropertyGrid _ownerGrid;

                public PropertyGridView(Control parent, MyPropertyGrid ownerGrid)
                {
                    _parent = parent;
                    _parent.HandleCreated += _owner_HandleCreated;
                    _parent.HandleDestroyed += _owner_HandleDestroyed;

                    _ownerGrid = ownerGrid;
                }

                protected override void WndProc(ref Message m)
                {
                    base.WndProc(ref m);

                    switch (m.Msg)
                    {
                        case (int)NativeMethods.WM_NCPAINT:
                        case (int)NativeMethods.WM_PAINT:

                            using (var g = _parent.CreateGraphics())
                            {
                                using (var pen = new Pen(_ownerGrid.LineColor))
                                {
                                    g.DrawRectangle(pen, 0, 0, _parent.Width - 1, _parent.Height - 1);
                                }
                            }

                            break;
                    }
                }

                void _owner_HandleDestroyed(object sender, EventArgs e)
                {
                    ReleaseHandle();
                }

                void _owner_HandleCreated(object sender, EventArgs e)
                {
                    AssignHandle(_parent.Handle);
                }
            }

            public class MyToolStripRenderer : ToolStripSystemRenderer
            {
                protected override void OnRenderToolStripBorder(ToolStripRenderEventArgs e)
                {
                    //base.OnRenderToolStripBorder(e);
                }
            }

            public MyPropertyGrid()
            {
                base.LineColor = SystemColors.Control;
                base.ViewBackColor = Color.FromArgb(246, 246, 246);

                base.DrawFlatToolbar = true;
                base.ToolStripRenderer = new MyToolStripRenderer();

                var docDocument = typeof(PropertyGrid)
                    .GetField("doccomment", BindingFlags.NonPublic | BindingFlags.Instance)
                    .GetValue(this) as Control;

                new SnappableControl(docDocument, this);

                var gridView = typeof(PropertyGrid)
                    .GetField("gridView", BindingFlags.NonPublic | BindingFlags.Instance)
                    .GetValue(this) as Control;

                new PropertyGridView(gridView, this);
            }

        }

    }

Captura de pantalla

Respondido el 01 de junio de 16 a las 01:06

Explain the context as well - vinoth krishnan

you will need a bit of interop for that:

[DllImport("User32", CharSet=CharSet.Auto)]
private static extern int SetWindowLong(IntPtr hWnd, int Index, int Value);
[DllImport("User32", CharSet=CharSet.Auto)]
private static extern int GetWindowLong(IntPtr hWnd, int Index);

int GWL_STYLE = -16;
int WS_BORDER = 0x00800000;
IntPtr hWnd = yourPropertyGrid.Handle;

int style = GetWindowLong(hWnd, GWL_STYLE);
style = style & ~WS_BORDER;
SetWindowLong(hWnd, GWL_STYLE, style);

contestado el 04 de mayo de 12 a las 07:05

Thank, @Jamie I tried this, but unfortunately the style already seems to omit the style, thus removing it, does not change. Have you tried your solution and had it working? - Uwe Keim

Hi Uwe, no, I haven't tried, it is just the standard way to remove the border of a native windows control. it seems that the propertygrid is not following this standard, so, I think you won't be able to do it in this way. - user694833

this code work.

private void SetHelpBoderColor(bool showBorder)
{
    if (showBorder)
    {
        //Set Default ViewBackColor
        PropertyInfo viewBackColor = this.propertyGrid.GetType().GetProperty("ViewBorderColor");
        if (viewBackColor != null)
            viewBackColor.SetValue(this.propertyGrid, SystemColors.ControlDark, null);

        //Set Default HelpBorderColor
        PropertyInfo helpBorderColor = this.propertyGrid.GetType().GetProperty("HelpBorderColor");
        if (helpBorderColor != null)
            helpBorderColor.SetValue(this.propertyGrid, SystemColors.ControlDark, null);

    }
    else
    {
        //Set ViewBackColor
        PropertyInfo viewBackColor = this.propertyGrid.GetType().GetProperty("ViewBorderColor");
        if (viewBackColor != null)
            viewBackColor.SetValue(this.propertyGrid, SystemColors.Control, null);

        //Set HelpBorderColor
        PropertyInfo helpBorderColor = this.propertyGrid.GetType().GetProperty("HelpBorderColor");
        if (helpBorderColor != null)
            helpBorderColor.SetValue(this.propertyGrid, SystemColors.Control, null);
    }

    if (DesignMode)
    {
        Parent.Refresh();
    }
}

contestado el 11 de mayo de 16 a las 11:05

Yes, that code can show or hide ViewBoder and HelpBoder in PropertyGrid. - TrungNV

One rapid and intuitive solution is to create a Panel de padres y Child Panel como en la siguiente imagen:

enter image description here

Respondido el 23 de enero de 19 a las 12:01

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.