我有自己的TreeView控件,完全是OwnerDraw'n:
myTreeView.DrawMode = TreeViewDrawMode.OwnerDrawAll;
Run Code Online (Sandbox Code Playgroud)
我试图实现的是根据当前的资源管理器主题绘制打开/关闭的字形.特别是在Vista和Win7盒子上,我希望看到新的支架(黑色三角形)而不是加号/减号.我知道,对于非OwnerDraw'n TreeView,这可以通过以下方式实现:
myTreeView.HandleCreated += delegate(object sender, EventArgs args)
{
MyNativeMethods.SetWindowTheme(myTreeView.Handle, "explorer", null);
};
Run Code Online (Sandbox Code Playgroud)
我认为VisualStyleRenderer让我绘制主题感知的字形:
VisualStyleRenderer r = new VisualStyleRenderer(VisualStyleElement.TreeView.Glyph.Opened);
r.DrawBackground(e.Graphics, e.Bounds);
Run Code Online (Sandbox Code Playgroud)
不幸的是,上面的代码在所有情况下都会绘制减号.看起来VisualStyleRenderer不尊重主题设置.
有人可以对此有所了解吗?谢谢!
dme*_*mex 19
我觉得我偶然发现这篇文章是件好事,当我开始更新我的一些项目所使用的所有者绘制的TreeView控件时,我想知道同样的事情,在上周的一些uxtheme hacking之后我发现了explorer使用的状态后来在这里发布了其他人:http://www.codeproject.com/KB/list/ObjectListView.aspx?msg = 3492581#xx3492581xx
以下是使用SetWindowTheme API时由Windows设置的未记录样式,此处未列出其他一些部件和状态ID,但它们似乎没用,我为了简洁我省略了错误检查和VisualStyleRenderer.IsElementDefined().
如果您需要在本机代码中使用它们,OpenThemeData/OpenThemeDataEx和DrawThemeBackground API也可以使用这些类名,状态和部件ID.
(这些由Glyph +/- expando图标使用)
VisualStyleRenderer OpenedRenderer = new VisualStyleRenderer("Explorer::TreeView", 2, 2);
VisualStyleRenderer ClosedRenderer = new VisualStyleRenderer("Explorer::TreeView", 2, 1);
Run Code Online (Sandbox Code Playgroud)
(当鼠标位于上面两个雕文上方时使用这两个)
VisualStyleRenderer HoverOpenedRenderer = new VisualStyleRenderer("Explorer::TreeView", 4, 2);
VisualStyleRenderer HoverClosedRenderer = new VisualStyleRenderer("Explorer::TreeView", 4, 1);
Run Code Online (Sandbox Code Playgroud)
(在TreeView项目上悬停状态)
VisualStyleRenderer ItemHoverRenderer = new VisualStyleRenderer("Explorer::TreeView", 1, 2);
Run Code Online (Sandbox Code Playgroud)
(选择状态TreeView项)
VisualStyleRenderer ItemSelectedRenderer = new VisualStyleRenderer("Explorer::TreeView", 1, 3);
Run Code Online (Sandbox Code Playgroud)
(选中但控制失去焦点时(此时.HideSelecton = False))
VisualStyleRenderer LostFocusSelectedRenderer = new VisualStyleRenderer("Explorer::TreeView", 1, 5);
Run Code Online (Sandbox Code Playgroud)
(还有另一个SelectedTreeView状态比默认状态(1-3)更暗,用于显示当前所有项目都被选中时当前选择的项目??)
VisualStyleRenderer Selectedx2Renderer = new VisualStyleRenderer("Explorer::TreeView", 1, 6);
Run Code Online (Sandbox Code Playgroud)
(将状态悬停在ListView项目上)
VisualStyleRenderer ItemHoverRenderer = new VisualStyleRenderer("Explorer::ListView", 1, 2);
Run Code Online (Sandbox Code Playgroud)
(选择状态TreeView项)
VisualStyleRenderer ItemSelectedRenderer = new VisualStyleRenderer("Explorer::ListView", 1, 3);
Run Code Online (Sandbox Code Playgroud)
(选中但控制失去焦点时(此时.HideSelecton = False))
VisualStyleRenderer LostFocusSelectedRenderer = new VisualStyleRenderer("Explorer::ListView", 1, 5);
Run Code Online (Sandbox Code Playgroud)
(同样还有另一个选定状态比默认状态(1-3)稍暗,用于显示当前所有项目都被选中时当前选择的项目??)
VisualStyleRenderer Selectedx2Renderer = new VisualStyleRenderer("Explorer::ListView", 1, 6);
Run Code Online (Sandbox Code Playgroud)
示例:(取自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);
}
Run Code Online (Sandbox Code Playgroud)
只需确保使用属性缓存VisualStyleRenderer的创建,这样当您的控件被绘制时,您不会读取uxtheme.dll 100次;)
private static VisualStyleRenderer closedRenderer;
public static VisualStyleRenderer ClosedRenderer
{
get
{
if (closedRenderer == null)
closedRenderer = new VisualStyleRenderer("Explorer::TreeView", 2, 1);
return closedRenderer;
}
}
Run Code Online (Sandbox Code Playgroud)
上面的示例使用缓存的VisualStyleRenderer:
protected virtual void DrawExpansionGlyphStyled(Graphics g, Rectangle r, bool isExpanded)
{
if (isExpanded)
OpenedRenderer.DrawBackground(g, r);
else
ClosedRenderer.DrawBackground(g, r);
}
Run Code Online (Sandbox Code Playgroud)
请享用.dmex
归档时间: |
|
查看次数: |
6397 次 |
最近记录: |