Как изменить цвет границы (или удалить границу) элемента управления PropertyGrid?

Наличие стандартного PropertyGrid элемента управления WinForms 2.0 Я ищу способ либо изменить цвет границы элемента управления, либо вообще удалить границу.

введите здесь описание изображения

Мне известно о свойстве LineColor который, к сожалению, меняет только внутренние границы между ячейками.

Кроме того, я использовал ILSpy для просмотра исходного кода элемента управления PropertyGrid и по-прежнему не нашел ничего значимого для себя.

Мой вопрос:

Как удалить внешнюю границу элемента управления PropertyGrid или изменить цвет внешней границы?

Обновление 2012-05-04 — Решение (также известное как "взлом"):

На основе ответа Джейми я собрал рабочее решение (которую можно скачать отсюда):

введите здесь описание изображения

Идея состоит в том, чтобы поместить сетку свойств внутри панели и позволить панели обрезать элемент управления.

При таком подходе я поместил обтравочную панель в другую панель с Padding равным «1» (или любым другим, что вы хотите, чтобы были границы), и присвоил этой панели BackColor, который служит цветом границы (зеленый в моем примере).

Установите Anchor сетки свойств на «Left, Right, Top, Bottom», установите Dock панели отсечения на «Full».

введите здесь описание изображения

Это хорошо работает для моих требований. Я бы расценил это как своего рода взлом, поскольку он потребляет ресурсы двух панелей, которые, как я надеялся, смогу сэкономить.


person Uwe Keim    schedule 03.05.2012    source источник


Ответы (5)


это еще одна альтернатива, так как кажется, что мой первый ответ не подходит для этого конкретного элемента управления. Это грязный трюк, но он должен работать:

Поместите элемент управления Panel в свое окно или диалоговое окно, скажем, размером 100H x 300V. Поместите сетку свойств внутрь панели с позицией -1,-1 и размером 102 302.

person Community    schedule 04.05.2012
comment
Хе-хе, я уже пробовал это в прошлом, но безуспешно. Я попробую еще раз, на всякий случай, если я сделал что-то не так. - person Uwe Keim; 04.05.2012
comment
@ Джейми Это сработало, спасибо за ваше предложение! Я обновлю свой вопрос с вашим ответом. - person Uwe Keim; 04.05.2012
comment
Будьте осторожны, это может быть байт при изменении размера окна из-за автоматического масштабирования формы. Вы действительно хотите написать код в обработчике события Resize панели, чтобы всегда убедиться, что PropertyGrid находится там, где он должен быть. - person Hans Passant; 04.05.2012

Вот код из моего проекта

В PropertyGrid есть два элемента управления, которые необходимо обработать.
+ doccomment — документ справки.
+ gridView, которые отображают значение свойства.

Эти элементы управления рисуют прямоугольник границы цветом ControlDark.

Нам нужно перерисовать прямоугольник с помощью HelpBackColor и LineColor, чтобы сделать вид более четким.

    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);
            }

        }

    }

Снимок экрана

person Dũng Nguyễn Ngọc    schedule 31.05.2016
comment
Объясните также контекст - person Vinoth Krishnan; 31.05.2016

для этого вам понадобится немного взаимодействия:

[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);
person Community    schedule 04.05.2012
comment
Спасибо, @Jamie, я пробовал это, но, к сожалению, стиль уже, кажется, опускает стиль, таким образом удаляя его, не меняется. Вы пробовали свое решение и оно сработало? - person Uwe Keim; 04.05.2012
comment
Привет, Уве, нет, я не пробовал, это просто стандартный способ удалить границу собственного элемента управления Windows. кажется, что propertygrid не соответствует этому стандарту, поэтому я думаю, что вы не сможете сделать это таким образом. - person ; 04.05.2012

этот код работает.

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();
    }
}
person TrungNV    schedule 11.05.2016
comment
Да, этот код может отображать или скрывать ViewBoder и HelpBoder в PropertyGrid. - person TrungNV; 12.05.2016

Одним из быстрых и интуитивно понятных решений является создание Родительской панели и Дочерней панели, как показано на следующем рисунке:

введите здесь описание изображения

person Moctar Haiz    schedule 23.01.2019