2011-08-20 29 views
12

Gli stili di visualizzazione di Microsoft per Winforms mi hanno sempre confuso.Colore del bordo dei controlli utilizzando VisualStyles

Sto cercando di avere uno Panel seduto accanto a uno TreeView e di avere lo stesso bordo di VisualStyle.

Border Colors

Come si può vedere, il confine TreeView è diverso rispetto ai miei tentativi di disegno nel mio Panel. BorderStyle del pannello è impostato su Nessuno.

Ho provato questo:

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

e Ho provato questo:

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

Qualche suggerimento per il colore del bordo visivo corretto o elemento visivo da usare?

risposta

8

Questo problema non è limitato a WinForms ... Poiché il controllo WinForms TreeView è semplicemente un wrapper attorno al controllo TreeView Win32 nativo, sta disegnando lo stesso stile di bordo di un controllo TreeView in qualsiasi altro punto del sistema, ad esempio Windows Explorer. E come hai osservato, lo stile del bordo 3D appare diverso con gli stili di visualizzazione abilitati rispetto a quelli delle versioni precedenti di Windows. In realtà non sembra affatto 3D — l'effetto è più vicino se si imposta il bordo su Single/FixedSingle, tranne che è un po 'troppo scuro rispetto a quello attorno al TreeView.

Per quanto riguarda il modo di replicare che per un controllo Panel, penso che il trucco non sta nel disegnare un bordo, ma piuttosto nel tracciare una sfondo.

Ci potrebbe essere una soluzione più elegante se P/Invoke il DrawThemeBackground function direttamente con alcuni dei Parts and States che non sono esposti nella confezione .NET VisualStyleRenderer, ma questo sembra piuttosto buono per me:

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

     

      (la TreeView si trova sulla sinistra, il pannello si trova sulla destra.)

0.123.

Se si desidera disegnare il bordo e abbinare i colori utilizzati quando sono abilitati gli stili visivi, è possibile farlo anche tu. Si tratta semplicemente di determinare il colore corretto e quindi di utilizzare le routine di disegno GDI + standard per disegnare una o due linee attorno al controllo.

Ma non accendere Photoshop ancora! I colori sono tutti documentati in un file denominato AeroStyle.xml, che si trova nella cartella include di Windows SDK. Ti interessano i valori globals; questi:

<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> 
+0

Sto giocando con DrawThemeBackground proprio ora. Paint.NET mi sta dicendo che il colore del bordo TreeView è (130, 135, 144). Il tuo suggerimento Tab.Pane.Normal era abbastanza vicino, ma era (137, 140, 149). – LarsTech

2

per tutti voi interessati, here ho trovato la soluzione, come si può lasciare disegnare lo sfondo di Windows corretta per il controllo (utilizzo definizione RECT da 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); 
    } 
}