我想删除节点类型为5或6的复选框。我使用这个代码:
private void TvOne_DrawNode(object sender, DrawTreeNodeEventArgs e)
{
int type = (e.Node as Node).typ;
if (type == 5 || type == 6)
{
Color backColor, foreColor;
if ((e.State & TreeNodeStates.Selected) == TreeNodeStates.Selected)
{
backColor = SystemColors.Highlight;
foreColor = SystemColors.HighlightText;
}
else if ((e.State & TreeNodeStates.Hot) == TreeNodeStates.Hot)
{
backColor = SystemColors.HotTrack;
foreColor = SystemColors.HighlightText;
}
else
{
backColor = e.Node.BackColor;
foreColor = e.Node.ForeColor;
}
using (SolidBrush brush = new SolidBrush(backColor))
{
e.Graphics.FillRectangle(brush, e.Node.Bounds);
}
TextRenderer.DrawText(e.Graphics, e.Node.Text, this.TvOne.Font,
e.Node.Bounds, foreColor, backColor);
if ((e.State & TreeNodeStates.Focused) == TreeNodeStates.Focused)
{
ControlPaint.DrawFocusRectangle(e.Graphics, e.Node.Bounds,
foreColor, backColor);
}
e.DrawDefault = false;
}
else
{
e.DrawDefault = true;
}
}
问题是,然后图像和线的根节点是不存在的。怎样才能删除复选框,让图像和线条在那里?
This is wrong!
4条答案
按热度按时间disho6za1#
在您所展示的代码中,您自己处理了类型为5或6的所有节点的绘图。对于其余类型,您只需允许系统以默认方式绘制节点。这就是为什么它们都有预期的线条,但你自己绘制的线条没有:你忘了画线了!你看,当你说
e.DrawDefault = false;
时,它假设你真的是这个意思。没有一个常规的绘图完成,包括标准线。你要么需要自己画这些线,要么想办法在没有主人画的情况下过日子。
从您现在拥有的代码来看,看起来您试图在自己绘制的代码中尽可能多地模拟系统的本地绘制风格,因此我不清楚您首先通过自己绘制来完成什么。如果你只是想让复选框不出现在类型5和6的节点上(就像线条一样,因为你没有画它们,所以没有画出来!)),有一种更简单的方法可以做到这一点,而不涉及所有者绘图。
所以,您会问,隐藏单个节点的复选框的更简单的方法是什么?好吧,事实证明
TreeView
控件本身实际上支持这一点,但该功能在.NET Framework中没有公开。你需要P/P并调用Windows API来获取它。将以下代码添加到表单类中(确保为System.Runtime.InteropServices
添加了using
声明):顶部所有乱七八糟的东西都是你的P/P声明。您需要几个常量,
TVITEM
structure描述树视图项的属性,SendMessage
function。底部是您实际调用的函数(HideCheckBox
)。您只需传入TreeView
控件和要从中删除复选标记的特定TreeNode
项。因此,您可以从每个子节点中删除复选标记,以获得类似于以下内容的内容:
mwngjboj2#
使用TreeViewExtensions。
使用示例:
下面是答案的代码作为一个扩展方法,使用这个你可以做:
ttvkxqim3#
很好啊!我唯一要做的修改是只将
TreeNode
而不是TreeView
传递给HideCheckBox
方法。可以从TreeNode
本身检索TreeView
:gstyhher4#
有一件事在所有答案中都没有提到,那就是当在选定的节点上按空格键时,复选框可能会重新出现。这意味着我们需要处理
TreeView.BeforeCheck
事件,以便在状态更改之前取消检查,并重新添加复选框。如果我们确切地知道哪些节点隐藏了复选框,那么我们可以添加事件并完成。这里的
e.Action
条件只有在我们使用IsCheckBoxHidden()
来避免在批量检查树视图节点时出现不必要的P/bankke时才重要。如果我们没有使用P/Pocke,那么逻辑就足够简单,不值得检查。如果你不能立即分辨出哪个节点的复选框被隐藏了,那么我们可以用更多的P/pickle来找到它。
或者,可以使用
TVM_GETITEMSTATE
代替TVM_GETITEM
。两者都可以完成任务,但后者需要SendMessage
的另一个重载。