问题如题 但是可能会比题目要复杂些
treeview的情况如下描述:
父节点有五个 A B C D E
父节点A 中有三个子节点 A1,A2,A3 ;父节点B 中有五个子节点 B1,B2,B3,B4,B5 ;
父节点C 中有七个子节点 C1,C2,C3,C4,C5,C6,C7;父节点 D 中有三个子节点D1,D2,D3;
父节点E中有三个子节点 E1,E2,E3
此时我选择了
父节点A 中的子节点 A1,A2,
父节点B 中子节点 B1,B2,B3,B4
父节点C 中子节点 C1,C2,C3,C4,C6,C7我要达到的目的是:
不论是父还是子节点,只要被选中,就返回 1 ,并被被字符串就收,选中10个节点,就有对应的10个字符串就收返回的 1
如果是没有被选中的子节点,有多少个没有被选中,那就返回多少个 0 ,同样也就有多少个字符串接收 0我现在只能对5个父节点进行判断,我的代码是: 
string a="",b="",c="",d="",e="";
if (treeview.Nodes["父节点A"].Checked) == true)
             {a="1";}
          else
             {a="0";}}
if (treeview.Nodes["父节点B"].Checked) == true)
             {b="1";}
          else
             {b="0";}}
if (treeview.Nodes["父节点C"].Checked) == true)
             {c="1";}
          else
             {c="0";}}
if (treeview.Nodes["父节点D"].Checked) == true)
             {d="1";}
          else
             {d="0";}}
if (treeview.Nodes["父节点E"].Checked) == true)
             {e="1";}
          else
             {e="0";}}
上面的代码只能针对父节点,如果加入了判断子节点(代码相同)是否被选中,程序就无法继续 被CATCH了请各位大侠帮个忙,在线等, 送分 100申明下 要在WINFORM中运行的程序

解决方案 »

  1.   

    不明白你这么做的意义。我觉得可以这样:给每个节点的Tag属性设置值,声明一个列表,无论哪个节点被选中,就往列表里插入Tag的值,插入前先判断是否存在,存在就不要插入;一旦取消了选择,就从列表里移除。感觉要比你用一大堆字符串好啊。
      

  2.   

    用递归判断就好了。如果你在绑定treeview时对每个Node的Tag设置为你的节点编号,就方便控制了,比如返回一个所有节点选中状态的列表:
    Dictionary<int,bool> nodesStatusDictionary = new Dictionary<int,bool>();private void startRead()
    {
        nodesStatusDictionary.Clear();
        foreach(TreeNode node in treeView.Nodes)
        {
            readStatus(node);
        }
        //这个时候treeview中所有节点的状态信息就读到了nodesStatusDictionary中了。
    }private void readStatus(TreeNode node)
    {
        nodesStatusDictionary.Add(Convert.ToInt32(node.Tag),node.Checked);
        foreach(TreeNode child in node.Nodes)
        {
            readStatus(child);
        }
    }
      

  3.   

    有了nodesStatusDictionary存放treeview的所有节点选中状态信息,那么你可以任意使用了,如果你想将选中写为1,未选中写为0,那么你作一下转换就可以了,不过我想我上面的代码,基本可以满足你的要求了。
    在任何时候你只要想获取treeview中所有节点选中状态信息,你只要调用startRead(),那么nodesStatusDictionary就是你想要的数据,当然你可以将startRead()方法这样改:
    private Dictionary <int,bool> startRead()
    {
        Dictionary <int,bool> nodesStatusDictionary = new Dictionary <int,bool>();
        foreach(TreeNode node in treeView.Nodes)
        {
            readStatus(node,ref nodesStatusDictionary);
        }    //这个时候treeview中所有节点的状态信息就读到了nodesStatusDictionary中了。
        return nodesStatusDictionary;
    }private void readStatus(TreeNode node,ref Dictionary <int,bool> nodesStatusDictionary)
    {
        nodesStatusDictionary.Add(Convert.ToInt32(node.Tag),node.Checked);
        foreach(TreeNode child in node.Nodes)
        {
            readStatus(child,ref nodesStatusDictionary);
        }
      

  4.   

    楼主可以把进入catch的地方标出啊,这样可以让大家看一下哪有问题。你帖个没问题的代码好像没什么用吧。
      

  5.   

    用递归
    up~
    private void  RootTree()
    {
    string treeAstr=string.empty;
    string treeBstr=string.empty;
    string treeCstr=string.empty;
    string treeDstr=string.empty;
    string treeEstr=string.empty;
    if (treeview.Nodes["父节点A"].IsExpanded)
         {treeAstr="1";
         ForeachTree(ref treeAstr,treeview.Nodes["父节点A"]);
         }
    if (treeview.Nodes["父节点B"].IsExpanded) 
       {treeBstr="1";
         ForeachTree(ref treeAstr,treeview.Nodes["父节点B"]);
    }
    if (treeview.Nodes["父节点C"].IsExpanded) 
         {treeCstr="1";
         ForeachTree(ref treeAstr,treeview.Nodes["父节点C"]);
    }if (treeview.Nodes["父节点D"].IsExpanded)
          {
         treeDstr="1";
         ForeachTree(ref treeAstr,treeview.Nodes["父节点D"]);
    }
    if (treeview.Nodes["父节点E"].IsExpanded) 
          {
              treeEstr="1";
              ForeachTree(ref treeAstr,treeview.Nodes["父节点E"]);
    }
    }
    private void ForeachTree(ref string Result,TreeNodeCollection childNodes)
    {
                  foreach (TreeNode nd in nodes)
                {
                    string a;
                    if (nd.Checked)
                        Result= Result+ "1";
                    else
                        Result= Result+ "0";
                    TreeNodeCollection tempnodes = nd.Nodes;
                    if (nd .Nodes .Count >0)
                        ForeachTree(result, tempnodes );             
                }
    }
    }
      

  6.   


    private void  RootTree() 

    string treeAstr=string.empty; 
    string treeBstr=string.empty; 
    string treeCstr=string.empty; 
    string treeDstr=string.empty; 
    string treeEstr=string.empty; 
    if (treeview.Nodes["父节点A"].IsExpanded) 
        {treeAstr="1"; 
        ForeachTree(ref treeAstr,treeview.Nodes["父节点A"]); 
        } 
    if (treeview.Nodes["父节点B"].IsExpanded) 
      {treeBstr="1"; 
        ForeachTree(ref treeAstr,treeview.Nodes["父节点B"]); 

    if (treeview.Nodes["父节点C"].IsExpanded) 
        {treeCstr="1"; 
        ForeachTree(ref treeAstr,treeview.Nodes["父节点C"]); 
    } if (treeview.Nodes["父节点D"].IsExpanded) 
          { 
        treeDstr="1"; 
        ForeachTree(ref treeAstr,treeview.Nodes["父节点D"]); 

    if (treeview.Nodes["父节点E"].IsExpanded) 
          { 
              treeEstr="1"; 
              ForeachTree(ref treeAstr,treeview.Nodes["父节点E"]); 


    private void ForeachTree(ref string Result,TreeNodeCollection childNodes) 

                  foreach (TreeNode nd in nodes) 
                { 
                    string a; 
                    if (nd.Checked) 
                        Result= Result+ "1"; 
                    else 
                        Result= Result+ "0"; 
                    TreeNodeCollection tempnodes = nd.Nodes; 
                    if (nd .Nodes .Count >0) 
                        ForeachTree(result, tempnodes );            
                } 


      

  7.   

    先回复 qldsrx(青龙白虎) 在标题中已经说明了意义,是我没有讲清楚:实际在程序里是这样子的
    举个程序里的例子:父节点:报表中心,子节点:会员资料报表,会员消费报表,会员充值报表,商品消费报表
    如果选中了子节点“会员资料报表”,返回值 1 ,否则返回 0 。
    当用户登陆的时候(子节点“会员资料报表”在表中对应的是VIPINFOR字段),进行判断,
    如果VIPINFOR字段的值是 1 ,那么有权限进行查看,如果是 0 则没有权限查看。
    这样子是不是就明白了。(其实我看好多程序里是用CHECKBOX来操作的)lovvver (向架构前进!)  的代码我还在看 ,我是个小号,看的时间可能会久些,呵呵。。happyboyxq (happyboyxq)  父节点的判断是 if (treeview.Nodes["父节点A"].Checked) == true) 
                {a="1";} 
              else 
                {a="0";}} 
    如果我子节点的判断也用 if (treeview.Nodes["子节点A"].Checked) == true) 
                {Za="1";} 
              else 
                {Za="0";}} 
    程序就无法继续了,他在判断的时候,在父节点中找不到 “子节点A”,所有就CATCH了 ,不过我在CATCH中没有写任何代码,只是最简单的不让程序在运行的时候报错而已 ,呵呵
      

  8.   

    先回复 qldsrx(青龙白虎) 在标题中已经说明了意义,是我没有讲清楚:实际在程序里是这样子的
    举个程序里的例子:父节点:报表中心,子节点:会员资料报表,会员消费报表,会员充值报表,商品消费报表
    如果选中了子节点“会员资料报表”,返回值 1 ,否则返回 0 。
    当用户登陆的时候(子节点“会员资料报表”在表中对应的是VIPINFOR字段),进行判断,
    如果VIPINFOR字段的值是 1 ,那么有权限进行查看,如果是 0 则没有权限查看。
    这样子是不是就明白了。(其实我看好多程序里是用CHECKBOX来操作的)lovvver (向架构前进!)  的代码我还在看 ,我是个小号,看的时间可能会久些,呵呵。。happyboyxq (happyboyxq)  父节点的判断是 if (treeview.Nodes["父节点A"].Checked) == true) 
                {a="1";} 
              else 
                {a="0";}} 
    如果我子节点的判断也用 if (treeview.Nodes["子节点A"].Checked) == true) 
                {Za="1";} 
              else 
                {Za="0";}} 
    程序就无法继续了,他在判断的时候,在父节点中找不到 “子节点A”,所有就CATCH了 ,不过我在CATCH中没有写任何代码,只是最简单的不让程序在运行的时候报错而已 ,呵呵
      

  9.   


    我晕倒,你怎么可以直接在父级操作第二层节点,这里面的查找需要一级级下去的啊。比如你要查找“子节点A”,而“子节点A”是"父节点A"的亲生儿子,那么你需要先找到这个爸爸"父节点A",要这样:
    if (treeview.Nodes["父节点A"].Nodes["子节点A"].Checked == true) 跳过父亲,程序就不知道是谁的儿子了。
      

  10.   

    貌似是个权限控制,但又好像是点击的时候才去控制,加载的时候不控制,全部加载的样子。那么你也就完全没必要使用2楼提供的递归遍历,2楼的方法是用在初始加载TreeView的时候的,全部节点遍历核对权限,无权限则不显示节点。而你那个可以通过节点的点击事件,直接判断选中的某个节点就可以了。
      

  11.   

      if (treeview.Nodes["父节点A"].Nodes["子节点A"].Checked == true) 
    你的这个很管用哎 ,可以达到我的目的,
    但是我发觉有个问题就是 ,我这么写重复的东西太多了,尽管这是我思考了很久的思路,
    希望有人能帮我一下,2楼的代码解释下,我觉得学到东西才是最重要的,所以先暂不结贴,
      

  12.   

    看到12楼了 其实不是点击的时候才去控制的
    当我在DATAGRIDVIEW中选中某个用户的时候,如果用户有操作“会员资料报表”的权限,那么在TREEVIEW中相对应的“会员资料报表”节点就被选中,此时我也可以更改为不选中状态 ,然后点击 BUTTON 按钮更新用户权限表,在用户登陆系统的时候,判断表中对应的值是 1 还是0  
      

  13.   

    如果你知道什么叫递归,2楼那个方法就很好理解。其实我经常用递归处理带有树状结构的数据,因为无需考虑层次数,说不定有更多的层次呢。这用在XML文档的处理上比较多。一个函数中再调用自己,那就是递归的方法,看似这样调用永无止境,但是一般在调用自己之前会判断下是否满足条件,满足才会调用。TreeView的递归调用其实是看是否存在子节点,通过遍历某个Node的所有子节点,然后针对每一个子节点再次遍历其下面的所有子节点,因为遍历的方法是一样的,所以再次遍历其下面的所有子节点的时候,还是可以使用那个函数,所以就调用自己就可以了。如果这样还是不能理解,说明你无法在头脑中建立树状结构,建议你画个树状图,在每个树的分支上标注方法,执行函数时顺着树状图去分析,那样会形象点。
      

  14.   

       对了 忘记6楼
     “ForeachTree(ref treeAstr,treeview.Nodes["父节点A"]); ”
    在我的程序里有错误 无法转为 TreeNodeCollection
    “string treeAstr=string.empty;”中的empty的e 要改成大写 E 
    我用的 是 2008 可能用的版本差异的造成的吧
      

  15.   


      哈哈 你说的一点都没有错 在此之前我对递归从未有任何认识
      不过我还是能懂得你说的 
    treeview 我在学校学的时候 老师都叫“树形结构”
     里面的节点就像树的枝干,枝干上有子枝干,子枝干上还有子枝干,
    这里遍历的时候应该就是“看”所有的第一层枝干,然后看第一层每个枝干的子枝干,然后再“看”每个子枝干的子枝干。。这里的 “看” 相当于在程序里写的方法,操作都是 一模一样的方法,
    我说的应该没有什么不对吧,可能有些不恰当吧
    看来我得好好学习下递归了
     谢谢! 
      

  16.   


    if ( ds != null )
    {
    for (int i = 0; i < ds.Tables[0].Rows.Count; i++ )
    {
    ChildNode = new TreeNode(ds.Tables[0].Rows[i]["Name"].ToString());
    ChildNode.Tag = ds.Tables[0].Rows[i]["Code"].ToString(); if ( Convert.ToInt32(ds.Tables[0].Rows[i]["Childs"]) > 0 )
    {
    ShowBarChilds(ChildNode,ds.Tables[0].Rows[i]["Code"].ToString());
    }
    Node.Nodes.Add(ChildNode);
    }
    }