自定义 TreeNode 边界
如何将 TreeView 节点的标准鼠标行为(如选择、热跟踪、双击扩展等)扩展到更广泛的节点区域?我有一个自定义绘制的节点,它的标签比系统绘制的标签更宽,并且当光标位于普通节点边界内时,它仅对鼠标操作做出反应。
有什么想法吗?
顺便说一句,拦截 TVM_GETITEMRECT 和 TVM_HITTEST 不会成功。
关于我正在做的事情的几句话:我正在开发一个 WinForms 树控件,它通常与 WinForms TreeView 完全相同,但也允许添加特殊节点,这些节点可以将自定义字体和颜色应用于其标签的任何部分。因此,它有点像“RichTreeView”,例如可以具有文本中带有粗体单个单词的节点。通过一些大量的字体修改,节点标签可能会比常规标签更宽,但也会更窄(这会导致抑制鼠标操作的另一个问题),因此我的问题。
How to extend the standard mouse behavior of a TreeView node (like selecting, hot tracking, expansion on double click etc.) over a wider node area? I've got a custom-drawn node that has a wider label than it would have if it was system-drawn and it only reacts to mouse actions when the cursor is within the ordinary node bounds.
Any Ideas?
BTW, intercepting TVM_GETITEMRECT and TVM_HITTEST won't do the trick.
A few words about what I'm doing: I'm developing a WinForms tree control that normally acts exactly the same as WinForms TreeView, but also allows for adding special nodes that can have custom fonts and colors applied to any parts of their labels. So it's kinda "RichTreeView" that can for example have nodes with bolded single words in their text. With some heavy font tinkering a node label can get way wider than regular, but also narrower (which causes another problem of suppressing mouse actions), hence my question.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
是的,这是本机 Windows 控件的问题。它没有任何方法来指定自定义项目边界。 TVN_GETDISPINFO 通知可能是最接近的,但 NMTVDISPINFO 缺少指定边界的方法。 .NET 包装器没有实现它。它实际上只够实现 VirtualMode。
这使得命中测试和 TreeNode.Bounds 保持基于原始指标。水平滚动条尤其存在问题,如果它比原始文本更宽,它就不会滚动得足够远以显示所有自定义绘制的文本。您可以通过实现 MouseDown 并迭代 TreeNode.Bounds 属性来解决命中测试问题,但不能解决滚动条问题。
对此没有干净的解决办法,只有一种丑陋的解决办法。将 TreeNode.Text 设置为足够宽的任意字符串以解决问题。如果需要,您可以使用 Tag 属性来存储实际文本。这取决于您绘制的自定义方式,在文本前添加几个 M 可能就足够了。不漂亮。
Yes, this is a problem with the native Windows control. It doesn't have any way to specify a custom item bounds. The TVN_GETDISPINFO notification is probably closest, but NMTVDISPINFO is missing a way to specify the bounds. The .NET wrapper doesn't implement it. It is really only good enough to implement a VirtualMode.
That keeps hit testing and TreeNode.Bounds based on the original metrics. It is especially a problem with the horizontal scrollbar, it won't scroll far enough to reveal all the custom-drawn text if it is wider than the original. You can somewhat solve the hit testing problem by implementing MouseDown and iterating the TreeNode.Bounds properties but not the scrollbar problem.
There's no clean fix for this, only an fugly one. Set the TreeNode.Text to an arbitrary string that's wide enough to solve the problem. You could use the Tag property to store the actual text, if necessary. It depends on how custom you draw, prefixing the Text with a couple of M's might be good enough. Not pretty.