微软的winforms视觉风格总是让我迷惑不解。
我正在尝试Panel
坐在TreeView
旁边,并且只有相同的VisualStyle边框。
正如您所看到的,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);
有关使用正确的可视边框颜色或视觉元素的任何建议吗?
答案 0 :(得分:8)
此问题不仅限于WinForms ...由于WinForms TreeView
控件只是本机Win32 TreeView控件的包装器,因此它在系统中的任何其他位置绘制与TreeView控件相同的边框样式,例如Windows资源管理器。正如您所观察到的,3D边框样式在启用视觉样式时看起来与在以前版本的Windows上看起来不同。它实际上看起来根本不是3D - 如果你将边框设置为Single
/ FixedSingle
,效果会更接近,除了它与TreeView周围的那个相比有点太暗。
至于如何为Panel
控件复制它,我认为诀窍不在于绘制边,而在于绘制背景
如果直接调用DrawThemeBackground
function以及.NET VisualStyleRenderer
包装中未公开的某些Parts and States,可能会有一个更优雅的解决方案,但是这个一个看起来对我很好:
VisualStyleRenderer renderer =
new VisualStyleRenderer(VisualStyleElement.Tab.Pane.Normal);
renderer.DrawBackground(e.Graphics, panel1.ClientRectangle);
(TreeView位于左侧; Panel位于右侧。)
如果您想自己绘制边框并匹配启用视觉样式时使用的颜色,您也可以这样做。这只是确定正确颜色的问题,然后使用标准的GDI +绘图程序在控件周围绘制一行或两行。
但是暂时不要启动Photoshop!这些颜色都记录在名为AeroStyle.xml
的文件中,该文件位于Windows SDK的include
文件夹中。您对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>
答案 1 :(得分:2)
对于所有感兴趣的人,here我找到了解决方案,如何让Windows为您的控件绘制正确的背景(使用pinvoke.net的RECT定义):
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);
}
}