C#:单击节点时,使用ownerdrawtext和奇怪的黑色高亮显示查看所有者图形
我将DrawMode设置为OwnerDrawText,并附加到DrawNode事件中,添加了我的代码以按照我想要的方式绘制文本,并且除了在选择节点时进行一些奇怪的黑色选择高亮显示外,所有工作都很好 没问题,我添加了逻辑来检查节点的状态是否高亮显示,并绘制了我自己的高亮显示,除了单击节点时添加的黑色高亮显示,而不仅仅是选中的。。。释放鼠标按钮后,高光会被我的矩形画出来,但确实会被画出来并闪烁……这很烦人/C#:单击节点时,使用ownerdrawtext和奇怪的黑色高亮显示查看所有者图形,c#,treeview,ownerdrawn,C#,Treeview,Ownerdrawn,我将DrawMode设置为OwnerDrawText,并附加到DrawNode事件中,添加了我的代码以按照我想要的方式绘制文本,并且除了在选择节点时进行一些奇怪的黑色选择高亮显示外,所有工作都很好 没问题,我添加了逻辑来检查节点的状态是否高亮显示,并绘制了我自己的高亮显示,除了单击节点时添加的黑色高亮显示,而不仅仅是选中的。。。释放鼠标按钮后,高光会被我的矩形画出来,但确实会被画出来并闪烁……这很烦人/ 显然,我忘了问我的问题了……如果不完全处理图纸,如何摆脱选择?以我的经验,你通常不能。要么你
显然,我忘了问我的问题了……如果不完全处理图纸,如何摆脱选择?以我的经验,你通常不能。要么你自己画,要么你不画。如果您试图在控件绘制的图形之上合成图形,则最终会出现故障 这有点痛苦,因为您必须自己处理聚焦矩形、选择高光和绘制所有glyph 从好的方面来说,它可以用来做大部分的工作 这里有一些代码可以帮助您实现这一点(它是不完整的,因为它使用了一些未包含的方法,并且它不能完全呈现普通treeview的功能,因为它支持渐变填充的项和列,但应该是一个方便的参考)
受保护的虚拟void OnDrawTreeNode(对象发送方,DrawTreeNodeEventArgs e)
{
字符串文本=e.Node.text;
矩形项rect=e.边界;
if(e.Bounds.Height<1 | e.Bounds.Width<1)
返回;
int cIndentBy=19;//TODO-支持缩进值
int cMargin=6;//TODO-这有点随机,它以某种方式从缩进中派生出来
int-cTwoMargins=cMargin*2;
int缩进=(e.Node.Level*cIndentBy)+cMargin;
int iconLeft=indent;//在何处绘制亲子关系线&icon/checkbox
int textLeft=iconLeft+16;//在何处绘制文本
Color leftcolor=e.Node.BackColor;
颜色文本颜色=e.Node.ForeColor;
if(位域.IsBitSet(例如状态,树状态.灰色))
textColour=Color.FromArgb(255128128128);
//渐变填充背景
刷背刷=新的SolidBrush(LeftColor);
e、 图形.FillRectangle(backBrush,itemRect);
//在每个项目的底部加上暗线
分色器颜色=colorutils.Mix(leftcolor,Color.FromArgb(255,0,0,0),0.02);
笔分离器笔=新笔(分离器颜色);
e、 图形.绘制线(分隔条,itemRect.Left,itemRect.Bottom-1,itemRect.Right,itemRect.Bottom-1);
//Bodged将按钮样式用作我的笔记本电脑上不可用的Treeview样式。。。
如果(!HideSelection)
{
if(Bitfield.IsBitSet(e.State,TreeNodeStates.Selected)| | Bitfield.IsBitSet(e.State,TreeNodeStates.Hot))
{
Rectangle selRect=新矩形(textLeft,itemRect.Top,itemRect.Right-textLeft,itemRect.Height);
VisualStyleRenderer=新的VisualStyleRenderer((包含焦点)?VisualStyleElement.Button.Button.Button.Hot
:VisualStyleElement.按钮.按钮.正常);
渲染器。牵引地面(如图形、SELECT);
//Bodge让视觉风格看起来像是探索者的选择-用alpha'd白色矩形进行透支,使颜色褪色很多
Brush bodge=新的SolidBrush(Color.FromArgb((Bitfield.IsBitSet(e.State,TreeNodeStates.Hot))?224:128255255);
e、 图形.圆角矩形(bodge,selRect);
}
}
Pen dotPen=新笔(颜色为argb(128128));
dotPen.DashStyle=DashStyle.Dot;
int midY=(itemRect.Top+itemRect.Bottom)/2;
//划定亲子关系
如果(显示行)
{
int x=cMargin*2;
if(e.Node.Level==0&&e.Node.PrevNode==null)
{
//树中的第一个节点有一条半高线
e、 图形绘制线(点笔、x、midY、x、itemRect.底部);
}
其他的
{
TreeNode testNode=e.Node;//与普通TreeView中一样,仅用于绘制到具有下一个同级节点的线
对于(int-iLine=e.Node.Level;iLine>=0;iLine--)
{
if(testNode.NextNode!=null)
{
x=(iLine*cIndentBy)+(cMargin*2);
e、 图形绘制线(点笔、x、itemRect.Top、x、itemRect.Bottom);
}
testNode=testNode.Parent;
}
x=(e.Node.Level*cIndentBy)+cTwoMargins;
e、 图形绘制线(点笔、x、itemRect.Top、x、midY);
}
e、 图形.抽绳(点笔、iconLeft+cMargin、midY、iconLeft+cMargin+10、midY);
}
//如果需要,绘制展开(加号/减号)图标
如果(ShowPlusMinus&&e.Node.Nodes.Count>0)
{
//使用VisualStyles渲染器使用正确的OS定义的图示符
矩形expandRect=新矩形(iconLeft-1,midY-7,16,16);
VisualStyleElement元素=(e.Node.IsExpanded)?VisualStyleElement.TreeView.Glyph.Opened
:VisualStyleElement.TreeView.Glyph.Closed;
VisualStyleRenderer=新的VisualStyleRenderer(元素);
渲染器。牵引地面(如图形、expandRect);
}
//绘制文本,文本由|个字符分隔成列
Point textStartPos=新点(itemRect.Left+textLeft,itemRect.Top);
点文本
protected virtual void OnDrawTreeNode(object sender, DrawTreeNodeEventArgs e)
{
string text = e.Node.Text;
Rectangle itemRect = e.Bounds;
if (e.Bounds.Height < 1 || e.Bounds.Width < 1)
return;
int cIndentBy = 19; // TODO - support Indent value
int cMargin = 6; // TODO - this is a bit random, it's slaved off the Indent in some way
int cTwoMargins = cMargin * 2;
int indent = (e.Node.Level * cIndentBy) + cMargin;
int iconLeft = indent; // Where to draw parentage lines & icon/checkbox
int textLeft = iconLeft + 16; // Where to draw text
Color leftColour = e.Node.BackColor;
Color textColour = e.Node.ForeColor;
if (Bitfield.IsBitSet(e.State, TreeNodeStates.Grayed))
textColour = Color.FromArgb(255,128,128,128);
// Grad-fill the background
Brush backBrush = new SolidBrush(leftColour);
e.Graphics.FillRectangle(backBrush, itemRect);
// Faint underline along the bottom of each item
Color separatorColor = ColourUtils.Mix(leftColour, Color.FromArgb(255,0,0,0), 0.02);
Pen separatorPen = new Pen(separatorColor);
e.Graphics.DrawLine(separatorPen, itemRect.Left, itemRect.Bottom-1, itemRect.Right, itemRect.Bottom-1);
// Bodged to use Button styles as Treeview styles not available on my laptop...
if (!HideSelection)
{
if (Bitfield.IsBitSet(e.State, TreeNodeStates.Selected) || Bitfield.IsBitSet(e.State, TreeNodeStates.Hot))
{
Rectangle selRect = new Rectangle(textLeft, itemRect.Top, itemRect.Right - textLeft, itemRect.Height);
VisualStyleRenderer renderer = new VisualStyleRenderer((ContainsFocus) ? VisualStyleElement.Button.PushButton.Hot
: VisualStyleElement.Button.PushButton.Normal);
renderer.DrawBackground(e.Graphics, selRect);
// Bodge to make VisualStyle look like Explorer selections - overdraw with alpha'd white rectangle to fade the colour a lot
Brush bodge = new SolidBrush(Color.FromArgb((Bitfield.IsBitSet(e.State, TreeNodeStates.Hot)) ? 224 : 128,255,255,255));
e.Graphics.FillRectangle(bodge, selRect);
}
}
Pen dotPen = new Pen(Color.FromArgb(128,128,128));
dotPen.DashStyle = DashStyle.Dot;
int midY = (itemRect.Top + itemRect.Bottom) / 2;
// Draw parentage lines
if (ShowLines)
{
int x = cMargin * 2;
if (e.Node.Level == 0 && e.Node.PrevNode == null)
{
// The very first node in the tree has a half-height line
e.Graphics.DrawLine(dotPen, x, midY, x, itemRect.Bottom);
}
else
{
TreeNode testNode = e.Node; // Used to only draw lines to nodes with Next Siblings, as in normal TreeViews
for (int iLine = e.Node.Level; iLine >= 0; iLine--)
{
if (testNode.NextNode != null)
{
x = (iLine * cIndentBy) + (cMargin * 2);
e.Graphics.DrawLine(dotPen, x, itemRect.Top, x, itemRect.Bottom);
}
testNode = testNode.Parent;
}
x = (e.Node.Level * cIndentBy) + cTwoMargins;
e.Graphics.DrawLine(dotPen, x, itemRect.Top, x, midY);
}
e.Graphics.DrawLine(dotPen, iconLeft + cMargin, midY, iconLeft + cMargin + 10, midY);
}
// Draw Expand (plus/minus) icon if required
if (ShowPlusMinus && e.Node.Nodes.Count > 0)
{
// Use the VisualStyles renderer to use the proper OS-defined glyphs
Rectangle expandRect = new Rectangle(iconLeft-1, midY - 7, 16, 16);
VisualStyleElement element = (e.Node.IsExpanded) ? VisualStyleElement.TreeView.Glyph.Opened
: VisualStyleElement.TreeView.Glyph.Closed;
VisualStyleRenderer renderer = new VisualStyleRenderer(element);
renderer.DrawBackground(e.Graphics, expandRect);
}
// Draw the text, which is separated into columns by | characters
Point textStartPos = new Point(itemRect.Left + textLeft, itemRect.Top);
Point textPos = new Point(textStartPos.X, textStartPos.Y);
Font textFont = e.Node.NodeFont; // Get the font for the item, or failing that, for this control
if (textFont == null)
textFont = Font;
StringFormat drawFormat = new StringFormat();
drawFormat.Alignment = StringAlignment.Near;
drawFormat.LineAlignment = StringAlignment.Center;
drawFormat.FormatFlags = StringFormatFlags.NoWrap;
string [] columnTextList = text.Split('|');
for (int iCol = 0; iCol < columnTextList.GetLength(0); iCol++)
{
Rectangle textRect = new Rectangle(textPos.X, textPos.Y, itemRect.Right - textPos.X, itemRect.Bottom - textPos.Y);
if (mColumnImageList != null && mColumnImageList[iCol] != null)
{
// This column has an imagelist assigned, so we use the column text as an integer zero-based index
// into the imagelist to indicate the icon to display
int iImage = 0;
try
{
iImage = MathUtils.Clamp(Convert.ToInt32(columnTextList[iCol]), 0, mColumnImageList[iCol].Images.Count);
}
catch(Exception)
{
iImage = 0;
}
e.Graphics.DrawImageUnscaled(mColumnImageList[iCol].Images[iImage], textRect.Left, textRect.Top);
}
else
e.Graphics.DrawString(columnTextList[iCol], textFont, new SolidBrush(textColour), textRect, drawFormat);
textPos.X += mColumnWidthList[iCol];
}
// Draw Focussing box around the text
if (e.State == TreeNodeStates.Focused)
{
SizeF size = e.Graphics.MeasureString(text, textFont);
size.Width = (ClientRectangle.Width - 2) - textStartPos.X;
size.Height += 1;
Rectangle rect = new Rectangle(textStartPos, size.ToSize());
e.Graphics.DrawRectangle(dotPen, rect);
// ControlPaint.DrawFocusRectangle(e.Graphics, Rect);
}
}