Цвет границ элементов управления с использованием VisualStyles - PullRequest
13 голосов
/ 20 августа 2011

Визуальные стили Microsoft для winforms всегда озадачивали меня.

Я пытаюсь расположить Panel рядом с TreeView и просто иметь ту же границу VisualStyle.

Border Colors

Как видите, граница TreeView отличается от моих попыток рисования в моем Panel. BorderStyle панели имеет значение None.

Я пробовал это:

  Rectangle r = new Rectangle(0, 0, panel1.ClientRectangle.Width - 1, panel1.ClientRectangle.Height - 1);
  using (Pen p = new Pen(VisualStyleInformation.TextControlBorder))
    e.Graphics.DrawRectangle(p, r);

и я попробовал это:

VisualStyleRenderer renderer = new VisualStyleRenderer(VisualStyleElement.TextBox.TextEdit.Normal);
renderer.DrawEdge(e.Graphics, panel1.ClientRectangle, 
         Edges.Bottom | Edges.Left | Edges.Right | Edges.Top,
         EdgeStyle.Sunken, EdgeEffects.Flat);

Какие-либо предложения по правильному использованию цвета визуального бордюра или визуального элемента?

Ответы [ 2 ]

8 голосов
/ 20 августа 2011

Эта проблема не ограничивается WinForms ... Поскольку элемент управления WinForms TreeView представляет собой просто оболочку вокруг собственного элемента управления Tree32 Win32, он рисует тот же стиль границы, что и элемент управления TreeView в любом месте системы, например как проводник Windows. И, как вы заметили, стиль 3D-границы выглядит с включенными визуальными стилями иначе, чем в предыдущих версиях Windows. На самом деле он совсем не выглядит 3D - эффект будет ближе, если вы установите границу на Single / FixedSingle, за исключением того, что он немного темнее по сравнению с окном вокруг TreeView.

Что касается того, как повторить это для Panel элемента управления, я думаю, что хитрость заключается не в рисовании edge , а скорее в background .

Возможно, будет более элегантное решение, если вы P / Invoke вызовете функцию DrawThemeBackground непосредственно вместе с некоторыми из Частей и состояний , которые не отображаются в .NET. VisualStyleRenderer обертка, но этот мне кажется довольно хорошим:

VisualStyleRenderer renderer =
              new VisualStyleRenderer(VisualStyleElement.Tab.Pane.Normal);
renderer.DrawBackground(e.Graphics, panel1.ClientRectangle);

(TreeView слева; панель справа.)


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

Но пока не запускайте Photoshop! Все цвета задокументированы в файле с именем AeroStyle.xml, расположенном в папке include Windows SDK. Вы заинтересованы в значениях globals; это:

<globals>
    <EdgeDkShadowColor> 100 100 100</EdgeDkShadowColor>
    <EdgeFillColor>     220 220 220</EdgeFillColor>
    <EdgeHighLightColor>244 247 252</EdgeHighLightColor>
    <EdgeLightColor>    180 180 180</EdgeLightColor>
    <EdgeShadowColor>   180 180 180</EdgeShadowColor>
    <GlowColor>         255 255 255</GlowColor>
</globals>
2 голосов
/ 13 сентября 2012

для всех вас, здесь Я нашел решение, как вы можете нарисовать Windows правильный фон для вашего элемента управления (используйте определение RECT от pinvoke.net):

const string CLASS_LISTVIEW = "LISTVIEW";
const int LVP_LISTGROUP = 2;

[DllImport("uxtheme.dll", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
private extern static int DrawThemeBackground(IntPtr hTheme, IntPtr hdc, int iPartId, int iStateId, ref RECT pRect, IntPtr pClipRect);

public static void DrawWindowBackground(IntPtr hWnd, Graphics g, Rectangle bounds)
{
    IntPtr theme = OpenThemeData(hWnd, CLASS_LISTVIEW);
    if (theme != IntPtr.Zero)
    {
      IntPtr hdc = g.GetHdc();
      RECT area = new RECT(bounds);
      DrawThemeBackground(theme, hdc, LVP_LISTGROUP, 0, ref area, IntPtr.Zero);
      g.ReleaseHdc();
      CloseThemeData(theme);
    }
}
...