C#Winforms Treeview自定义复选框

C#Winforms Treeview自定义复选框,c#,winforms,treeview,C#,Winforms,Treeview,我正在开发一个实用程序,它可以帮助我构建长的、重复的HTML表。我有从XML文件导入的数据,一个显示名称的列表框,以及将文本插入包含XML中某些数据的richTextBox的按钮,但我必须为每个名称手动输入信息 我有一个树状视图,列出了委员会(家长)和小组委员会(1级儿童)。我可以选中相应的框,单击按钮,然后创建所有相应的HTML。但是,每个委员会(和小组)都有一名主席和一名排名靠前的成员。我没有在每个父节点和子节点下添加这两个额外的节点,而是有71个父节点和子节点。我不想再添加142个节点——

我正在开发一个实用程序,它可以帮助我构建长的、重复的HTML表。我有从XML文件导入的数据,一个显示名称的列表框,以及将文本插入包含XML中某些数据的richTextBox的按钮,但我必须为每个名称手动输入信息

我有一个树状视图,列出了委员会(家长)和小组委员会(1级儿童)。我可以选中相应的框,单击按钮,然后创建所有相应的HTML。但是,每个委员会(和小组)都有一名主席和一名排名靠前的成员。我没有在每个父节点和子节点下添加这两个额外的节点,而是有71个父节点和子节点。我不想再添加142个节点——我希望有一种方法可以选中“四点”复选框。。。?第一次单击=选中标记;第二个=绿色;第三个=红色;4th=已清除。或类似的。这样,我就可以“检查”是否是会员,“双重检查”主席,“三重检查”排名,第四次就可以重新开始了


我也愿意接受关于另一种方法的建议。这是最后一点,我需要开始工作,以节省我手动键入2-3K行HTML,所以我不在乎我如何完成它。谢谢。

好的,对不起,好久不见了。你知道,生活等等。无论如何,我结束了自己的TreeNode和TreeView课程。这是我第一次在WinForms上冒险,所以很多事情看起来都很挑剔。结果比我想象的要简单得多。如果有人想用这个,把你自己击倒

选中*.bmp图像只是我在其中添加颜色的复选框。我可能会为此制作自己的四幅图像,并整理populateStateMageList()方法。此外,我认为这将适用于您需要的任意多个州,最多可达StateImageList的14个图像限制

using System.Drawing;
using System.Windows.Forms;

namespace jkHTMLBuilder
{
    public class QuadCheckTreeNode : TreeNode
    {
        public enum CheckState : int { UnChecked, Checked, Chair, Rank }    // The four possible states
        private CheckState _cs = CheckState.UnChecked;                      // The node's current state

        public CheckState checkState
        {
            get
            {
                return _cs;
            }
            set
            {
                _cs = value;
            }
        }

        public QuadCheckTreeNode(string initString) : base()
        {
            this.Text = initString;
            this.checkState = CheckState.UnChecked;
            this.Checked = false;
            this.StateImageIndex = 0;
        }

        public void checkAdvance()                                          // This is called from onAfterCheck to set the next consecutive state
        {
            switch (checkState)
            {
                case CheckState.UnChecked:
                    checkState = CheckState.Checked;
                    break;
                case CheckState.Checked:
                    checkState = CheckState.Chair;
                    break;
                case CheckState.Chair:
                    checkState = CheckState.Rank;
                    break;
                case CheckState.Rank:
                    checkState = CheckState.UnChecked;
                    break;
            }

            this.Checked = (this.checkState == CheckState.UnChecked ? false : true);
        }
    }

    class QuadCheckTreeView : TreeView
    {
        private bool clickStop = false;
        private bool shouldAdvance = false;
        public QuadCheckTreeView() : base()
        {
            StateImageList = new ImageList();
        }

        public void populateStateImageList()                                // I made this a separate method and call it from my Load_Senators method so the images are
        {                                                                   // set up when the XML file is loaded.  Apparently, loading the files ( Check*.bmmp )
            for (int i = 0; i < 2; i++)                                     // from the ctor causes problems...?  Whatever.  This works.
            {
                Bitmap bmp = new Bitmap(16, 16);
                Graphics chkGraphics = Graphics.FromImage(bmp);
                switch (i)
                {
                    case 0:
                        CheckBoxRenderer.DrawCheckBox(chkGraphics, new Point(0, 1), System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal);
                        break;
                    case 1:
                        CheckBoxRenderer.DrawCheckBox(chkGraphics, new Point(0, 1), System.Windows.Forms.VisualStyles.CheckBoxState.CheckedNormal);
                        break;
                }

                StateImageList.Images.Add(bmp);
            }
            Bitmap myBitmap = new Bitmap("..\\..\\CheckBlue.bmp");
            StateImageList.Images.Add(myBitmap);
            myBitmap = new Bitmap("..\\..\\CheckRed.bmp");
            StateImageList.Images.Add(myBitmap);
        }                               

        public void ClearNodes(TreeNodeCollection nodes)                    // This is for when I move on to the next record.  Unchecks everything.
        {
            clickStop = true;
            foreach (QuadCheckTreeNode qctn in nodes)
            {
                qctn.Checked = false;
                qctn.checkState = QuadCheckTreeNode.CheckState.UnChecked;
                if (qctn.Nodes.Count > 0)
                {
                    foreach (QuadCheckTreeNode cqctn in qctn.Nodes)
                    {
                        cqctn.Checked = false;
                        cqctn.checkState = QuadCheckTreeNode.CheckState.UnChecked;
                    }
                }
            }
            clickStop = false;
        }

        protected override void OnCreateControl()
        {
            base.OnCreateControl();
            CheckBoxes = false;                                             // Checkboxes off to use my images
            ClearNodes(this.Nodes);                                         // Probably not needed.
        }

        protected override void OnNodeMouseClick(TreeNodeMouseClickEventArgs e)
        {
            base.OnNodeMouseClick(e);

            TreeViewHitTestInfo tvhtInfo = HitTest(e.X, e.Y);               // If you didn't click on it, ignore.
            if (tvhtInfo == null || tvhtInfo.Location !=
            TreeViewHitTestLocations.StateImage)
            {
                return;
            }

            QuadCheckTreeNode qctn = (QuadCheckTreeNode)e.Node;             // If you right-clicked, set to UnChecked
            if (e.Button == MouseButtons.Right)
            {
                if (qctn.checkState != QuadCheckTreeNode.CheckState.UnChecked)
                {
                    qctn.checkState = QuadCheckTreeNode.CheckState.UnChecked;
                    qctn.Checked = false;
                    shouldAdvance = false;
                }
            }
            else
                shouldAdvance = true;                                       // Left click sets this var==true so the node's Advance() method is called

            qctn.Checked = qctn.Checked;                                    // This fires the onAfterCheck event
        }

        protected override void OnAfterCheck(TreeViewEventArgs e)
        {
            base.OnAfterCheck(e);

            if (clickStop)                                                  // This keeps the event from running if it's called inappropriately
            {
                return;
            }

            clickStop = true;

            QuadCheckTreeNode qctn = (QuadCheckTreeNode)e.Node;
            if (shouldAdvance)
            {
                qctn.checkAdvance();
                shouldAdvance = false;
                qctn.StateImageIndex = (int)qctn.checkState;
            }

            checkParent(qctn);                                              // Calling this method, if it actually checks a parent node, won't call onAfterCheck because of clickStop

            clickStop = false;
        }

        protected void checkParent(QuadCheckTreeNode qctn)
        {
            QuadCheckTreeNode pqctn = (QuadCheckTreeNode)qctn.Parent;
            if (pqctn == null)
                return;
            if (pqctn.checkState == QuadCheckTreeNode.CheckState.UnChecked) // This checks a parent if it has a checked child
            {
                bool chkParent = false;

                foreach (QuadCheckTreeNode n in pqctn.Nodes)
                {
                    if (n.checkState != QuadCheckTreeNode.CheckState.UnChecked)     // Checks all the children.  If even one is checked, the parent gets checked
                        chkParent = true;
                }
                if (chkParent)
                {
                    pqctn.Checked = true;
                    pqctn.checkState = QuadCheckTreeNode.CheckState.Checked;
                }
            }
        }

    }
}
使用系统图;
使用System.Windows.Forms;
命名空间jkHTMLBuilder
{
公共类QuadCheckTreeNode:TreeNode
{
public enum CheckState:int{UnChecked,Checked,Chair,Rank}//四种可能的状态
私有CheckState _cs=CheckState.UnChecked;//节点的当前状态
公共检查状态检查状态
{
得到
{
返回(cs),;
}
设置
{
_cs=价值;
}
}
公共QuadCheckTreeNode(string initString):base()
{
this.Text=initString;
this.checkState=checkState.UnChecked;
这个.Checked=false;
this.stateMageIndex=0;
}
public void checkAdvance()//从onAfterCheck调用它以设置下一个连续状态
{
开关(检查状态)
{
case CheckState.UnChecked:
checkState=checkState.Checked;
打破
案例检查状态。已检查:
checkState=checkState.主席;
打破
案例检查状态。主席:
checkState=checkState.Rank;
打破
案例检查状态。等级:
checkState=checkState.UnChecked;
打破
}
this.Checked=(this.checkState==checkState.UnChecked?false:true);
}
}
类QuadCheckTreeView:TreeView
{
私有bool clickStop=false;
private bool shouldAdvance=假;
public QuadCheckTreeView():base()
{
StateImageList=新的ImageList();
}
public void populateStateImageList()//我将其作为一个单独的方法,并从Load_Senators方法调用它,因此图像是
{//在加载XML文件时设置。显然,正在加载文件(请选中*.bmmp)
对于(int i=0;i<2;i++)//来自于ctor会导致问题…?不管怎样。这是有效的。
{
位图bmp=新位图(16,16);
Graphics chkGraphics=Graphics.FromImage(bmp);
开关(一)
{
案例0:
CheckBoxRenderer.DrawCheckBox(chkGraphics,新点(0,1),System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal);
打破
案例1:
CheckBoxRenderer.DrawCheckBox(chkGraphics,新点(0,1),System.Windows.Forms.VisualStyles.CheckBoxState.CheckedNormal);
打破
}
stateMageList.Images.Add(bmp);
}
位图myBitmap=新位图(“..\\..\\CheckBlue.bmp”);
stateMageList.Images.Add(myBitmap);
myBitmap=新位图(“..\\..\\CheckRed.bmp”);
stateMageList.Images.Add(myBitmap);
}                               
public void ClearNodes(TreeNodeCollection节点)//这是在我转到下一条记录时使用的。取消选中所有内容。
{
单击停止=真;
foreach(节点中的QuadCheckTreeNode qctn)
{
qctn.Checked=假;
qctn.checkState=QuadCheckTreeNode.checkState.UnChecked;
如果(qctn.Nodes.Count>0)
{
foreach(qctn.节点中的QuadCheckTreeNode cqctn)
{
cqctn.Checked=假;
cqctn.checkState=QuadCheckTreeNode.checkState.UnChecked;
}
}
}
clickStop=false;
}
受保护的重写void OnCreateControl()
{
base.OnCreateControl();
checkbox=false;//禁用复选框以使用我的图像
ClearNode