我正在使用常规的WinForm Outlook Addin并且我使用DrawNode事件创建了一个Treeview,树正在按预期工作但是节点点击有一个小故障,只有绿色区域可以点击而半个节点没有响应。
当我使用MouseDown
事件时,整个区域都可以点击,包括节点旁边的空白区域。
但是要限制这个空白点击我在TreeViewHitTestLocations
的帮助下使用逻辑我正在检查点击的位置是否为RightOfLabel
然后不做任何事情,但不幸的是这不会给我一个精确的结果,它会以某种方式混淆并将标签的一半(节点)作为空格并且不会被点击。
注意:我认为这一切都发生了,因为我使用了DrawNode方法并且在保持标签和工作区图标之间的距离时,下面的应用程序假定标签在绿色部分内完成,因此红色部分留作空白区域。这只是我基于我对该方法所做的所有天真事情的假设。
如果有人可以指导我修复此问题,需要帮助来解决此问题。感谢
void treeview_mousedown(object sender, MouseEventArgs e)
{
TreeNode nodeClicked;
// if arrow up/down will be excluded from the mousedown event
var hitTest = this.HitTest(e.Location);
if (hitTest.Location == TreeViewHitTestLocations.PlusMinus)
return;
if (hitTest.Location == TreeViewHitTestLocations.RightOfLabel)
return;
// Get the node clicked on
nodeClicked = this.GetNodeAt(e.X, e.Y);
// Was the node clicked on?
if (!(nodeClicked == null))
this.SelectedNode = nodeClicked;
}
下面是我正在使用的treeview drawode方法:
void treeview_DrawNode(object sender, DrawTreeNodeEventArgs e)
{
Rectangle nodeRect = e.Node.Bounds;
// below location is the expand and collapse icon location
Point ptExpand = new Point(nodeRect.Location.X - 7, nodeRect.Location.Y + 5);
Image expandImg = null;
// check the below condition for nodes with child nodes and nodes without child nodes
if ( e.Node.Nodes.Count < 1)
expandImg = global::myresource.OfficeAddin.Controls.Resource.search;
else if (e.Node.IsExpanded && e.Node.Nodes.Count > 1)
expandImg = global::myresource.OfficeAddin.Controls.Resource.down_arrow_icon;
else
expandImg = global::myresource.OfficeAddin.Controls.Resource.right_arrow_icon;
Graphics g = Graphics.FromImage(expandImg);
IntPtr imgPtr = g.GetHdc();
g.ReleaseHdc();
e.Graphics.DrawImage(expandImg, ptExpand);
// draw node icon
Point ptNodeIcon = new Point(nodeRect.Location.X - 4, nodeRect.Location.Y + 2);
Image nodeImg = global::myresource.OfficeAddin.Controls.Resource.folder_icon_16px;
g = Graphics.FromImage(nodeImg);
imgPtr = g.GetHdc();
g.ReleaseHdc();
e.Graphics.DrawImage(nodeImg, ptNodeIcon);
// draw node text
Font nodeFont = e.Node.NodeFont;
if (e.Node.NodeFont != null)
{
nodeFont = e.Node.NodeFont;
} else {
nodeFont = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
}
// set the forecolor
Color forecolor = e.Node.ForeColor;
// color same as the font color
string strSelectedColor = @"#505050";
Color selectedColor = System.Drawing.ColorTranslator.FromHtml(strSelectedColor);
SolidBrush selectedTreeBrush = new SolidBrush(selectedColor);
//Inflate to not be cut
Rectangle textRect = nodeRect;
//below value controls the width of the text if given less then, long texts will come in multiple lines
textRect.Width += 150;
// below value controls the over all width of the node, if given less all the things will get sqeeze
e.Graphics.DrawString(e.Node.Text, nodeFont, selectedTreeBrush , Rectangle.Inflate(textRect, -20, 0));
}
答案 0 :(得分:0)
您的假设是正确的,您可以通过在绘图上标记边界来检查它,例如:
TreeNodeStates state = e.State;
bool isFocused = (state & TreeNodeStates.Focused) == TreeNodeStates.Focused;
if (isFocused)
ControlPaint.DrawFocusRectangle(e.Graphics, e.Bounds, foreColor, backColor);
您的代码存在更多问题:
问题1:图片
如果您使用节点图标,请使用TreeView.ImageList
和TreeNode.ImageKey
属性。否则,在绘图时不会为图像分配空间。在这种情况下,您可以使用TreeViewDrawMode.OwnerDrawText
DrawMode
。
问题2:字体
请勿使用除节点或树的字体之外的其他字体,因为它可能具有意外的大小。如果此 SegoeUI 字体是默认字体,请在TreeView
实例中使用它。然后,您可以获得所需的字体:
Font font = e.Node.NodeFont ?? e.Node.TreeView.Font;
问题3:文字
您使用Graphics.DrawString
来绘制使用GDI +的文本。但是,从.NET 2.0开始,默认文本呈现方法是GDI,除非控件的CompatibleTextRendering
属性为true。它们会产生略微不同的文字大小。
要使用GDI,计算标签的大小,请改用TextRenderer
类:
TextRenderer.DrawText(e.Graphics, e.Node.Text, font, e.Bounds, foreColor, TextFormatFlags.GlyphOverhangPadding | TextFormatFlags.SingleLine | TextFormatFlags.EndEllipsis | TextFormatFlags.NoPrefix);