none
VS2008 TreeView问题 RRS feed

  • 问题

  • 1、创建一个TreeView,深度为3;设置其属性CheckBoxs为True;

         根节点

            --子节点1

                --叶子节点

    2、我做的功能,选择根节点后,子节点和叶子节点选中(用的递归)。

    3、重复点击根节点的复选框,10次以上。当点击复选框的时候,此节点会闪烁一下。那么问题就来了。

         这样的话,节点的Checked状态和界面上显示的不一样。

         当界面上此节点选中,那么Checked状态为false,如果节点未选中,那么checked状态为true。

    是微软bug。建议在尽早修改。

     

    Visual Studio 2008    操作系统:Win7家庭普通版

    2011年3月11日 8:16

答案

  • 你好,

    这并不是微软的BUG,而是你的Code中存在逻辑问题,我没有具体测试时哪里出了问题,不过我对你的code做了一点点测试,可以看出Node的状态是没有问题的。

    if (e.Action == TreeViewAction.ByMouse)
                {
                    tnNode = e.Node;
                    if (e.Node.Checked)
                    {
                        AddFun(e.Node);
                        //选中节点之后,选中节点的所有子节点
                        SetChildNodeCheckedState(tnNode, true);
                        //选中父节点
                        SetParentNodeCheckedState(tnNode, true);
                    }
                    else
                    {
                        RemoveFun(e.Node);
                        //取消节点选中状态之后,取消所有子节点的选中状态
                        SetChildNodeCheckedState(tnNode, false);
                    }
                    //这里加一个Message,每次更改完状态就show一下当前node的状态

                    MessageBox.Show(e.Node.Name + "    " + e.Node.Checked.ToString());
                }

    这样可以看出每次更改状态后是正确的。


    如果您对我们的论坛在线支持服务有任何的意见或建议,请通过邮件告诉我们。
    MSDN 论坛好帮手 立刻免费下载  MSDN 论坛好帮手
    2011年3月15日 5:18

全部回复

  • 你好!

    这可能是其它代码所致不是 BUG,你可以将你的代码发出来大家帮你看看。


    知识改变命运,奋斗成就人生!
    2011年3月11日 8:25
    版主
  • TreeNode tnNode;

    /// <summary>
            /// 权限树的AfterCheck事件
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void tvFunction_AfterCheck(object sender, TreeViewEventArgs e)
            {
                if (e.Action == TreeViewAction.ByMouse)
                {
                    tnNode = e.Node;
                    if (e.Node.Checked)
                    {
                        AddFun(e.Node);
                        //选中节点之后,选中节点的所有子节点
                        SetChildNodeCheckedState(tnNode, true);
                        //选中父节点
                        SetParentNodeCheckedState(tnNode, true);
                    }
                    else
                    {
                        RemoveFun(e.Node);
                        //取消节点选中状态之后,取消所有子节点的选中状态
                        SetChildNodeCheckedState(tnNode, false);
                    }
                }
            }

     /// <summary>
            /// 取消节点选中状态之后,取消所有父节点的选中状态
            /// </summary>
            /// <param name="currNode">当前的TreeNode</param>
            /// <param name="state">状态</param>
            private void SetParentNodeCheckedState(TreeNode currNode, bool state)
            {
                TreeNode parentNode = currNode.Parent;
                if (parentNode == null)
                {
                    return;
                }
                parentNode.Checked = state;

                if (state)//选中
                {
                    AddFun(parentNode);
                }
                else
                {
                    RemoveFun(parentNode);
                }
                if (parentNode.Parent != null)
                {
                    SetParentNodeCheckedState(currNode.Parent, state);
                }
            }

            /// <summary>
            /// 选中节点之后,选中节点的所有子节点
            /// </summary>
            /// <param name="currNode">当前的TreeNode</param>
            /// <param name="state">状态</param>
            private void SetChildNodeCheckedState(TreeNode currNode, bool state)
            {
                foreach (TreeNode tn in currNode.Nodes)
                {
                    tn.Checked = state;
                    if (state)//选中
                    {
                        AddFun(tn);
                    }
                    else
                    {
                        RemoveFun(tn);
                    }
                    SetChildNodeCheckedState(tn, state);
                }
            }

            /// <summary>
            /// 添加功能
            /// </summary>
            /// <param name="tn"></param>
            private void AddFun(TreeNode tn)
            {
                dicFuns[tn.Name] = tn.Text;//这表示,无则添加,有则修改
            }

            /// <summary>
            /// 移除功能
            /// </summary>
            /// <param name="tn">TreeNode</param>
            private void RemoveFun(TreeNode tn)
            {
                if (dicFuns.ContainsKey(tn.Name))
                    dicFuns.Remove(tn.Name);
            } 

     

    private void Submit_Click(object sender, EventArgs e)
            {

    MessageBox.Show(tnNode.Checked.ToString());

    }

    2011年3月12日 2:44
  • 你好,

    这并不是微软的BUG,而是你的Code中存在逻辑问题,我没有具体测试时哪里出了问题,不过我对你的code做了一点点测试,可以看出Node的状态是没有问题的。

    if (e.Action == TreeViewAction.ByMouse)
                {
                    tnNode = e.Node;
                    if (e.Node.Checked)
                    {
                        AddFun(e.Node);
                        //选中节点之后,选中节点的所有子节点
                        SetChildNodeCheckedState(tnNode, true);
                        //选中父节点
                        SetParentNodeCheckedState(tnNode, true);
                    }
                    else
                    {
                        RemoveFun(e.Node);
                        //取消节点选中状态之后,取消所有子节点的选中状态
                        SetChildNodeCheckedState(tnNode, false);
                    }
                    //这里加一个Message,每次更改完状态就show一下当前node的状态

                    MessageBox.Show(e.Node.Name + "    " + e.Node.Checked.ToString());
                }

    这样可以看出每次更改状态后是正确的。


    如果您对我们的论坛在线支持服务有任何的意见或建议,请通过邮件告诉我们。
    MSDN 论坛好帮手 立刻免费下载  MSDN 论坛好帮手
    2011年3月15日 5:18