zoukankan      html  css  js  c++  java
  • 获取Treeview中CheckBox选中项的技巧(winform)

    背景

    今天,在做一个指纹管理平台的界面上,遇到了一些问题,因为公司的基础库中没有针对Winform平台的操作,所以在一个部门选择的场景中,关于如何获取部门TreeView中被选中的项目被难住了。所幸还有一个神器叫做搜索引擎,故谷歌一番,发现Asp.net下的这个问题很好解决,但是关于Winform平台下的类似问题,如凤毛麟角啊!

    当然,今天我也是查了很久,终于发现了两篇不错的文章,帮助我解决了这个问题,不敢独享,结合自己对使用其方法的心得,特意记录下来,并通过一个小例子和大家一起分享。

    问题是这样的

    有一个部门列表,多级的(或者说无限极),我们在Winform端列出来(这个很简单)后,需要对其进行部分的选择,然后通过一个按钮,提交选择好的部门,进入下一个业务操作场景,今天我遇到的问题就是,如何获取这个部门TreeView中,各个级别所选取的项目呢?如下图:

    问题描述在这里只是用一个例子来说明,所以就简单一点吧,如左图所示,我们的任务就是通过程序获取被选中的部门,将其信息送到下一个业务场景之中,在传统的Asp.net中,Web.UI下的Treeview控件提供了很方便的接口方法,用于获取被选中的项目,但是来到了Winform下,瞬间杯催……

    发现不能用Asp.net的思路来做这个事情后,我立马谷歌了一下,发现如下这篇文章,说的很不错,基本上解决了我遇到的问题,原文地址如下:“时空隧道

    我总结了一下,原作者的大概思路应该如下:

    流程图图1-简单的流程图示意

    解决问题:

    在页面(窗体)申明两个变量:

    • 第一个是用于存放被选项目的,文中是StringBuilder对象。
    • 第二个是一个Tag标签,按照原文的话就是“我们在TreeView的结点中用Tag来附加了CheckBox是否选中的标识信息”,字符串对象。

    用代码来描述就是如下形式:

    string tag = "True";//Tag标签
    StringBuilder nodesTag;//容器

    接下来,我们就开始去处理AfterCheck事件,让程序能够“记住”我们选择过的项目。无论大家有没有看过那篇文章,其中提到过“树的递归算法”,关于算法,大家可以参考如下这个链接:点击穿越

    在了解完算法后,相信大家能离家如下一段的代码了吧:这里就照搬这位博友的code了

    遍历方法
    private void TraversNodes(TreeNode parent)
    {
    TreeNode node
    = parent;
    if (node != null)
    {
    if (node.Tag != null && node.Tag.ToString() == tag)
    nodesTag.AppendFormat(
    "node:{0} has checked\n", node.Text);

    if (node.FirstNode != null)////如果node节点还有子节点则进入遍历
    {
    TraversNodes(node.FirstNode);
    }
    if (node.NextNode != null)////如果node节点后面有同级节点则进入遍历
    {
    TraversNodes(node.NextNode);
    }
    }
    }

    AfterCheck事件代码:

    treeView1_AfterCheck
    private void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
    { http://www.elivn.com/
    if (e.Action != TreeViewAction.Unknown)
    {
    TreeNode node
    = e.Node;
    if (node.Tag == null)
    node.Tag
    = tag;//附加结点信息
    else
    node.Tag
    = null;

    CheckAllChildNodes(e.Node, e.Node.Checked);

    //选中父节点
    bool bol = true;
    if (e.Node.Parent != null)
    {
    for (int i = 0; i < e.Node.Parent.Nodes.Count; i++)
    {
    if (!e.Node.Parent.Nodes[i].Checked)
    bol
    = false;
    }
    e.Node.Parent.Checked
    = bol;

    ////记得如果父节点被选中或取消,记得设置它的tag哦
    if (bol)
    {
    e.Node.Parent.Tag
    = tag;
    }
    else
    {
    e.Node.Parent.Tag
    = null;
    }
    }
    }
    }

    这个方法的调用时机应该是什么时候呢?对于我的场景来说,应该是再点击那个业务按钮之后,在之前,我们的AfterCheck事件代码唯一要做的事情就是如下图所示的一个流程:

    当我们点击业务按钮之后,为其添加如下代码即可:

    再好一点:

    到这里呢,按理说问题已经被解决完了。我们获取到了选中的部门,但是,按照常规来说,应该“选中节点的时候,如果节点存在子节点,可以选中全部的子节点;如果取消一个节点的选中状态,当前节点同时又存在父节点的话,就取消父节点的选中状态”,怎么办呢

    好啦,根据原文的意思,我们结合之前的获取选中状态的代码,修改如下:

    新的AfterCheck
    private void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
    {
    if (e.Action != TreeViewAction.Unknown)
    {
    TreeNode node
    = e.Node;
    if (node.Tag == null)
    node.Tag
    = tag;//附加结点信息
    else
    node.Tag
    = null;

    CheckAllChildNodes(e.Node, e.Node.Checked);

    //选中父节点
    bool bol = true;
    if (e.Node.Parent != null
    )
    {
    for (int i = 0; i < e.Node.Parent.Nodes.Count; i++
    )
    {
    if (!
    e.Node.Parent.Nodes[i].Checked)
    bol
    = false
    ;
    }

    e.Node.Parent.Checked
    = bol;

    ////记得如果父节点被选中或取消,记得设置它的tag哦
    if (bol)
    {
    e.Node.Parent.Tag
    = tag;
    }
    else
    {
    e.Node.Parent.Tag
    = null;
    }
    }
    }
    }

    新的CheckAllChildNodes方法:

    根据博友Flynn2009的提示,应该注意代码需要有修改,如下:

    node.Tag = nodeChecked ? (bool)tag : null;

    新的CheckAllChildNodes
    private void CheckAllChildNodes(TreeNode treeNode, bool nodeChecked)
    {
    foreach (TreeNode node in treeNode.Nodes)
    {
    node.Checked
    = nodeChecked;
    node.Tag
    = tag;////记得在这里为选中的项目设置tag属性
    if (node.Nodes.Count > 0)
    {
    this.CheckAllChildNodes(node, nodeChecked);
    }
    }
    }

    结束:

    好啦,在这里呢,我们就完成了获取Treeview中CheckBox选中状态的小例子,并且呢,还人性化的设置了一个关于父子选项的效果。文章就到这里为止吧,希望能给大家带来收获。欢迎拍砖!!!

    最后附上本文的示例项目代码:Vs2008+.Net 2.0

    点击获取

    转自http://www.cnblogs.com/seoxs/archive/2011/04/14/2015996.html

    天星直播:http://www.jkav.tk 论坛:http://www.tvb168.tk/bbs

  • 相关阅读:
    iaas,paas,saas理解
    July 06th. 2018, Week 27th. Friday
    July 05th. 2018, Week 27th. Thursday
    July 04th. 2018, Week 27th. Wednesday
    July 03rd. 2018, Week 27th. Tuesday
    July 02nd. 2018, Week 27th. Monday
    July 01st. 2018, Week 27th. Sunday
    June 30th. 2018, Week 26th. Saturday
    June 29th. 2018, Week 26th. Friday
    June 28th. 2018, Week 26th. Thursday
  • 原文地址:https://www.cnblogs.com/hyruur/p/2023346.html
Copyright © 2011-2022 走看看