我正在winforms
使用.NET 3.5
使用c#
。现在我想在父节点和子节点中的复选框中添加treeview ...
我已通过以下代码完成父节点创建。
dt = conn.dataTable("select desgn from designation");
tvRoles.Nodes.Clear();
foreach (DataRow dr in dt.Rows)
{
TreeNode parent = new TreeNode();
parent.Text = dr[0].ToString();
string value = dr[0].ToString();
parent.Expand();
tvRoles.Nodes.Add(parent);
subLevel(parent, value);
}
现在我想在子节点中添加复选框..
你能帮助我吗?
答案 0 :(得分:1)
我花了一天时间找到合适的解决方案: http://dotnetfollower.com/wordpress/2011/05/winforms-treeview-hide-checkbox-of-treenode/
解决方案是使用新类继承treeview和treenode,您可以使用新的treenode类而不使用复选框。添加了一个事件来处理隐藏的复选框。
下面的是从链接复制的类:
/// <summary>
/// Represents a node with hidden checkbox
/// </summary>
public class HiddenCheckBoxTreeNode : TreeNode
{
public HiddenCheckBoxTreeNode() { }
public HiddenCheckBoxTreeNode(string text) : base(text) { }
public HiddenCheckBoxTreeNode(string text, TreeNode[] children) : base(text, children) { }
public HiddenCheckBoxTreeNode(string text, int imageIndex, int selectedImageIndex) : base(text, imageIndex, selectedImageIndex) { }
public HiddenCheckBoxTreeNode(string text, int imageIndex, int selectedImageIndex, TreeNode[] children) : base(text, imageIndex, selectedImageIndex, children) { }
protected HiddenCheckBoxTreeNode(SerializationInfo serializationInfo, StreamingContext context) : base(serializationInfo, context) { }
}
public class MixedCheckBoxesTreeView : TreeView
{
/// <summary>
/// Specifies the attributes of a node
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct TV_ITEM
{
public int Mask;
public IntPtr ItemHandle;
public int State;
public int StateMask;
public IntPtr TextPtr;
public int TextMax;
public int Image;
public int SelectedImage;
public int Children;
public IntPtr LParam;
}
public const int TVIF_STATE = 0x8;
public const int TVIS_STATEIMAGEMASK = 0xF000;
public const int TVM_SETITEMA = 0x110d;
public const int TVM_SETITEM = 0x110d;
public const int TVM_SETITEMW = 0x113f;
public const int TVM_GETITEM = 0x110C;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam, ref TV_ITEM lParam);
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
// trap TVM_SETITEM message
if (m.Msg == TVM_SETITEM || m.Msg == TVM_SETITEMA || m.Msg == TVM_SETITEMW)
// check if CheckBoxes are turned on
if (CheckBoxes)
{
// get information about the node
TV_ITEM tv_item = (TV_ITEM)m.GetLParam(typeof(TV_ITEM));
HideCheckBox(tv_item);
}
}
protected void HideCheckBox(TV_ITEM tv_item)
{
if (tv_item.ItemHandle != IntPtr.Zero)
{
// get TreeNode-object, that corresponds to TV_ITEM-object
TreeNode currentTN = TreeNode.FromHandle(this, tv_item.ItemHandle);
HiddenCheckBoxTreeNode hiddenCheckBoxTreeNode = currentTN as HiddenCheckBoxTreeNode;
// check if it's HiddenCheckBoxTreeNode and
// if its checkbox already has been hidden
if(hiddenCheckBoxTreeNode != null)
{
HandleRef treeHandleRef = new HandleRef(this, Handle);
// check if checkbox already has been hidden
TV_ITEM currentTvItem = new TV_ITEM();
currentTvItem.ItemHandle = tv_item.ItemHandle;
currentTvItem.StateMask = TVIS_STATEIMAGEMASK;
currentTvItem.State = 0;
IntPtr res = SendMessage(treeHandleRef, TVM_GETITEM, 0, ref currentTvItem);
bool needToHide = res.ToInt32() > 0 && (currentTvItem.State & currentTvItem.StateMask) != 0;
if (needToHide)
{
// specify attributes to update
TV_ITEM updatedTvItem = new TV_ITEM();
updatedTvItem.ItemHandle = tv_item.ItemHandle;
updatedTvItem.Mask = TVIF_STATE;
updatedTvItem.StateMask = TVIS_STATEIMAGEMASK;
updatedTvItem.State = 0;
// send TVM_SETITEM message
SendMessage(treeHandleRef, TVM_SETITEM, 0, ref updatedTvItem);
}
}
}
}
protected override void OnBeforeCheck(TreeViewCancelEventArgs e)
{
base.OnBeforeCheck(e);
// prevent checking/unchecking of HiddenCheckBoxTreeNode,
// otherwise, we will have to repeat checkbox hiding
if (e.Node is HiddenCheckBoxTreeNode)
e.Cancel = true;
}
}
答案 1 :(得分:0)
您不能在同一TreeView上使用混合复选框状态作为标准,它可以是全部或全部。但是,我挖了一些挖掘并发现Disable TreeView Node Checkbox - 它可能会帮助你。
答案 2 :(得分:0)
如果您只希望子节点有复选框,这是一个解决方案:
//First, as I said, you have to set treeView.CheckBoxes = true;
//Second, set treeView.DrawMode = TreeViewDrawMode.OwnerDrawAll;
//Add this DrawNode event handler and enjoy =)
private void treeView_DrawNode(object sender, DrawTreeNodeEventArgs e)
{
if (e.Node.Parent == null)//If the Node is a Parent
{
int d = (int)(0.2*e.Bounds.Height);
Rectangle rect = new Rectangle(d + treeView.Margin.Left, d + e.Bounds.Top, e.Bounds.Height - d*2, e.Bounds.Height - d*2);
e.Graphics.FillRectangle(new SolidBrush(Color.FromKnownColor(KnownColor.Control)), rect);
e.Graphics.DrawRectangle(Pens.Silver, rect);
StringFormat sf = new StringFormat() { LineAlignment = StringAlignment.Center, Alignment = StringAlignment.Center };
e.Graphics.DrawString(e.Node.IsExpanded ? "-" : "+", treeView.Font, new SolidBrush(Color.Blue), rect, sf);
//Draw the dotted line connecting the expanding/collapsing button and the node Text
using (Pen dotted = new Pen(Color.Black) {DashStyle = System.Drawing.Drawing2D.DashStyle.Dot})
{
e.Graphics.DrawLine(dotted, new Point(rect.Right + 1, rect.Top + rect.Height / 2), new Point(rect.Right + 4, rect.Top + rect.Height / 2));
}
//Draw text
sf.Alignment = StringAlignment.Near;
Rectangle textRect = new Rectangle(e.Bounds.Left + rect.Right + 4, e.Bounds.Top, e.Bounds.Width - rect.Right - 4, e.Bounds.Height);
if (e.Node.IsSelected)
{
SizeF textSize = e.Graphics.MeasureString(e.Node.Text, treeView.Font);
e.Graphics.FillRectangle(new SolidBrush(SystemColors.Highlight), new RectangleF(textRect.Left, textRect.Top, textSize.Width, textRect.Height));
}
e.Graphics.DrawString(e.Node.Text, treeView.Font, new SolidBrush(treeView.ForeColor), textRect,sf);
}
else e.DrawDefault = true;
}
为了做得更好,您可能想要创建自己的TreeView
,覆盖OnDrawNode
(使用与我上面发布的代码相同的代码)并在构造函数中设置DoubleBuffered=true
。