13

Microsoft の winforms のビジュアル スタイルは、常に私を困惑させてきました。

私は a の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);

正しい視覚的な境界線の色または視覚要素を使用するための提案はありますか?

4

2 に答える 2

8

この問題は WinForms に限定されるものではありません... WinFormsTreeViewコントロールはネイティブの Win32 TreeView コントロールの単なるラッパーであるため、Windows Explorer など、システム内の他の場所で TreeView コントロールと同じ境界線スタイルを描画しています。また、ご覧のとおり、ビジュアル スタイルを有効にすると、以前のバージョンの Windows とは 3D 境界線のスタイルが異なって見えます。実際にはまったく 3D に見えません。境界線をSingle/FixedSingleに設定すると効果が近くなりますが、TreeView の周囲に比べて少し暗すぎます。

コントロールでそれを再現する方法に関してPanel言えば、コツはエッジを描くことではなく、背景を描くことにあると思います。

.NET ラッパーで公開されていない一部のパーツと状態と共にDrawThemeBackground関数を直接P/Invoke する場合、より洗練された解決策があるかもしれませんが、これは私にはかなり良さそうです。VisualStyleRenderer

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

   

   (TreeView は左側にあり、パネルは右側にあります。)


境界線を自分で描画し、視覚スタイルが有効になっているときに使用される色に合わせたい場合は、それも可能です。これは、正しい色を決定し、標準の GDI+ 描画ルーチンを使用してコントロールの周りに 1 本または 2 本の線を描画するだけの問題です。

ただし、まだ Photoshop を起動しないでください。色はすべて、Windows SDKAeroStyle.xmlのフォルダーにあるという名前のファイルに記載されています。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>
于 2011-08-20T15:14:42.703 に答える
2

興味のあるすべての人のために、ここで解決策を見つけました。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);
    }
}
于 2012-09-13T11:55:42.717 に答える