VisualStyleRenderer и темы (WinForms) - PullRequest
12 голосов
/ 10 июня 2010

У меня есть свой собственный элемент управления TreeView, который полностью OwnerDraw'n:

  myTreeView.DrawMode = TreeViewDrawMode.OwnerDrawAll;

Я пытаюсь нарисовать открытый / закрытый глиф в соответствии с текущей темой проводника. Особенно на Vista и Win7 я хотел бы видеть новые глифы (черные треугольники) вместо знаков плюс / минус. Я знаю, для не-OwnerDraw'n TreeView это может быть достигнуто следующим образом, который отлично работает:

  myTreeView.HandleCreated += delegate(object sender, EventArgs args)
  {
     MyNativeMethods.SetWindowTheme(myTreeView.Handle, "explorer", null);
  };

Я думал, что VisualStyleRenderer позволяет мне рисовать глифы с учетом темы:

  VisualStyleRenderer r = new VisualStyleRenderer(VisualStyleElement.TreeView.Glyph.Opened);
  r.DrawBackground(e.Graphics, e.Bounds);

Код выше, к сожалению, рисует знак минус во всех случаях. Похоже, VisualStyleRenderer не соблюдает настройки темы.

Может кто-то пролить свет на это? Спасибо!

1 Ответ

18 голосов
/ 12 июня 2010

Полагаю, это хорошо, что я наткнулся на этот пост, я хотел знать то же самое, когда начал обновлять элемент управления TreeView, нарисованный владельцем, используемый некоторыми моими проектами, после некоторого взлома на прошлой неделе я обнаружил, что используются состоянияby explorer, а затем разместил их здесь для других: http://www.codeproject.com/KB/list/ObjectListView.aspx?msg=3492581#xx3492581xx

Вот стили недокументированные , установленные Windows при использовании API SetWindowTheme. Есть несколько других идентификаторов деталей и состояний, которые неперечисленные здесь, но они не кажутся полезными, я опускаю проверку ошибок и VisualStyleRenderer.IsElementDefined () для краткости.

Эти имена классов, состояния и идентификаторы частей могут также использоваться API OpenThemeData / OpenThemeDataEx и DrawThemeBackground, если вытребует их использования в собственном коде.

Стили Explorer TreeView:

(Используются значками Glyph +/- expando)

VisualStyleRenderer OpenedRenderer = new VisualStyleRenderer("Explorer::TreeView", 2, 2);
VisualStyleRenderer ClosedRenderer = new VisualStyleRenderer("Explorer::TreeView", 2, 1); 

(Эти два используютсякогда мышь находится над двумя вышеуказанными символами)

VisualStyleRenderer HoverOpenedRenderer = new VisualStyleRenderer("Explorer::TreeView", 4, 2);
VisualStyleRenderer HoverClosedRenderer = new VisualStyleRenderer("Explorer::TreeView", 4, 1); 

(состояние наведения на TreeView item)

VisualStyleRenderer ItemHoverRenderer = new VisualStyleRenderer("Explorer::TreeView", 1, 2); 

(выбранный элемент TreeView состояния)

VisualStyleRenderer ItemSelectedRenderer = new VisualStyleRenderer("Explorer::TreeView", 1, 3);

(выбран, но когда элемент управления потерял фокус (когда this.HideSelecton = False))

VisualStyleRenderer LostFocusSelectedRenderer = new VisualStyleRenderer("Explorer::TreeView", 1, 5); 

(есть также другое состояние SelectedTreeView, которое немного темнее, чем значение по умолчанию (1-3), используемое для отображения того, какой элемент выбран в настоящий момент, когда все элементы выбраны в настоящее время ??)

VisualStyleRenderer Selectedx2Renderer = new VisualStyleRenderer("Explorer::TreeView", 1, 6); 

Explorer ListViewСтили:

(состояние наведения на элемент ListView)

VisualStyleRenderer ItemHoverRenderer = new VisualStyleRenderer("Explorer::ListView", 1, 2); 

(выбранное состояние TreeView)

VisualStyleRenderer ItemSelectedRenderer = new VisualStyleRenderer("Explorer::ListView", 1, 3);

(выбирается, но когда элемент управления потерял фокус (когда это.HideSelecton = False))

VisualStyleRenderer LostFocusSelectedRenderer = new VisualStyleRenderer("Explorer::ListView", 1, 5); 

(снова есть еще одно выбранное состояние, которое немного темнее, чем по умолчанию (1-3), используемое для отображения того, какой элемент выбран в настоящий момент, когда все элементы выбраны в настоящий момент??)

VisualStyleRenderer Selectedx2Renderer = new VisualStyleRenderer("Explorer::ListView", 1, 6); 

Пример: (взято из ObjectListView)

protected virtual void DrawExpansionGlyphStyled(Graphics g, Rectangle r, bool isExpanded)
{
VisualStyleElement glowelement = VisualStyleElement.CreateElement("Explorer::TreeView", 2, 1);

if (isExpanded)
glowelement = VisualStyleElement.CreateElement("Explorer::TreeView", 2, 2);

VisualStyleRenderer renderer = new VisualStyleRenderer(glowelement);
renderer.DrawBackground(g, r);
} 

Просто убедитесь, что вы кэшируете создание VisualStyleRenderer со свойством, так что вы не читаетеeme.dll 100 раз в секунду, когда ваш элемент управления окрашивается;)

private static VisualStyleRenderer closedRenderer;
public static VisualStyleRenderer ClosedRenderer
{
   get
   {
       if (closedRenderer == null)
          closedRenderer = new VisualStyleRenderer("Explorer::TreeView", 2, 1);

       return closedRenderer;
   }    
}

приведенный выше пример с использованием кэшированного VisualStyleRenderer:

protected virtual void DrawExpansionGlyphStyled(Graphics g, Rectangle r, bool isExpanded)
{

if (isExpanded)
   OpenedRenderer.DrawBackground(g, r);
else
   ClosedRenderer.DrawBackground(g, r);
} 

Наслаждайтесь.dmex

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...