none
求教育:为什么我的treeview显示的速度慢呢? RRS feed

  • 问题

  • 我的数据库是access,做了个公司的架构,用treeview显示出来,但是当我全屏时总是发现treeview显示数据很慢,估计要2秒以后才显示。

    下面的图片是别人做的软件界,打开软件界面,左边的架构和右边的dataGridView能同时显示出来,求教育!!

    我绑定的数据是使用递归算法,也使用过非递归的方法,但是一直无法改进。

    2013年5月16日 10:03

答案

全部回复

  • tree只需先展开当时节点下边的第一层,等user点了下一层节点之后再展开那个节点的下一层,如此便省了递归,您试试这法子


    Best regards

    2013年5月16日 15:33
  • tree只需先展开当时节点下边的第一层,等user点了下一层节点之后再展开那个节点的下一层,如此便省了递归,您试试这法子


    Best regards


    非常感谢您的回复,我已经试过了,还是不行哦。只要全屏就慢,为什么别人也是全屏速度就很快呢?
    2013年5月17日 22:44
  • 您把这软件放到别人电脑里全屏试试,看下是不是环境问题


    Best regards

    2013年5月18日 1:31
  • 也不行哦,换到别的电脑不行,我还删除后重新拉treeview,速度也是慢。

    2013年5月18日 8:33
  • 方便的话贴下代码吧。

    对了,您公司架构里头有几个人啊?



    Best regards

    2013年5月19日 0:58
  • 方便的话贴下代码吧。

    对了,您公司架构里头有几个人啊?



    Best regards

          private void CreatetvwUnit(int FatherID, TreeNode NodeName, TreeView tvw, DataTable TableName)
            {
                //获取公司名称
                OleDbDataReader UnitName = Operate.getRead("tb_Company");//创建数据读取器
                UnitName.Read();
                string comName = UnitName["CompanyName"].ToString();//得到公司的名称,作为根节点

                //获取数据集
                DataSet unitDset = Operate.getTable("select * from tb_Department", "tb_Department");
                TableName = unitDset.Tables[0];//获取datatable表

                //创建数据视图        
                DataView UnitView = new DataView(TableName);//创建数据视图用于筛选;          
                UnitView.RowFilter = "[ParentsId]=" + FatherID;//以父节点ID作为过滤条件,筛选数据视中的数据
                foreach (DataRowView unitRow in UnitView)
                {
                    TreeNode UnitNode = new TreeNode();//声明节点
                    UnitNode.ForeColor = Color.MediumBlue;//为节点的字体设为深蓝色
                    tvw.ImageList = imageList1;//设置树节点
                    if (NodeName == null)//判断节点是否为空值
                    {
                        //添加部门名称
                        UnitNode.Text = comName;//将公司名称传入,作为根节点
                        UnitNode.Name = "0";//将0传入,作为根节点的子节点ID
                        UnitNode.Tag = "0";//将0传入,作根节点的父节点ID
                        tvw.Nodes.Add(UnitNode);//添加进节点
                        UnitNode.ImageIndex = 0;
                        CreatetvwUnit(Int32.Parse(unitRow["ChildId"].ToString()), UnitNode, tvw, TableName);    //递归
                    }
                    else
                    {
                        //添加当前节点的子节点
                        UnitNode.Text = unitRow["ClassName"].ToString();
                        UnitNode.Name = unitRow["ChildId"].ToString();
                        UnitNode.Tag = unitRow["ParentsId"].ToString();
                        NodeName.Nodes.Add(UnitNode);//添加节点
                        UnitNode.ImageIndex = 0;
                        CreatetvwUnit(Int32.Parse(unitRow["ChildId"].ToString()), UnitNode, tvw, TableName);  //递归
                    }
                }
                UnitName.Dispose();//释放资源
            }


    2013年5月19日 9:25
  •   DataSet unitDset = Operate.getTable("select * from tb_Department", "tb_Department");
                TableName = unitDset.Tables[0];//获取datatable表

    你看你上面的代码,递归一次就会从数据读取一次,这至少是一处问题。放在方法外面,只读取一次


    知识改变命运,奋斗成就人生!

    2013年5月20日 1:49
    版主
  •   DataSet unitDset = Operate.getTable("select * from tb_Department", "tb_Department");
                TableName = unitDset.Tables[0];//获取datatable表

    你看你上面的代码,递归一次就会从数据读取一次,这至少是一处问题。放在方法外面,只读取一次


    知识改变命运,奋斗成就人生!

    有道理,我试试。我现在这里有非递归的,可否帮我看看有什么问题,我这个也显示的非常慢。

     private void tvName()
            {
                string strSql="select * from tb_Department where ParentsId>0 order by ParentsId";
                DataSet dsFirm = Operate.getTable(strSql, "tb_Department");

                TreeNode rootNode = new TreeNode();
                OleDbDataReader readFirm = Operate.getRead("tb_Company")
                if (readFirm.HasRows)
                {
                    readFirm.Read();         
                    rootNode.Text = readFirm["CompanyName"].ToString();
                    rootNode.Name = "0";
                    rootNode.Tag = "0";
                    this.tvInpro.Nodes.Add(rootNode);
                    this.tvInpro.SelectedNode = rootNode;
                    tvInpro.SelectedNode = tvInpro.TopNode;
                    if (dsFirm != null)
                    {
                        foreach (DataRow dr in dsFirm.Tables[0].Rows)
                        {
                            rootNode = new TreeNode();
                            rootNode.Text = dr["ClassName"].ToString();
                            rootNode.Name = dr["ChildId"].ToString();
                            rootNode.Tag = dr["ParentsId"].ToString();
                            if (tvInpro.SelectedNode != rootNode.Tag)
                            {
                                TreeNode[] tn_temp = tvInpro.Nodes.Find(dr["ParentsId"].ToString(), true);
                                if (tn_temp.Length > 0)
                                {
                                    tvInpro.SelectedNode = tn_temp[0];
                                }
                            }
                            tvInpro.SelectedNode.Nodes.Add(rootNode);//创建子节点
                        }

                    }
                    readFirm.Dispose();
                }
                else
                {
                    MessageBox.Show("架构中找不到公司名称!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    readFirm.Dispose();
                    this.Close();
                }
                tvInpro.ExpandAll();//展开所有节点

            }

    2013年5月20日 3:17
  • hello,

    你是否將所有的資料全部讀到TreeView裡了?我並沒有看到你寫出處發子節點展開的代碼

    處理節點前要調用BeginUpdate,然後在調用EndUpdate

    private void InitializeTreeView()
    {
        treeView1.BeginUpdate();
        treeView1.Nodes.Add("Parent");
        treeView1.Nodes[0].Nodes.Add("Child 1");
        treeView1.Nodes[0].Nodes.Add("Child 2");
        treeView1.Nodes[0].Nodes[1].Nodes.Add("Grandchild");
        treeView1.Nodes[0].Nodes[1].Nodes[0].Nodes.Add("Great Grandchild");
        treeView1.EndUpdate();
    }
    實際案例請參考

    http://www.dotblogs.com.tw/yc421206/archive/2009/07/28/9701.aspx
    http://www.dotblogs.com.tw/yc421206/archive/2011/03/12/21808.aspx


    秘訣無它,唯勤而已 http://www.dotblogs.com.tw/yc421206/

    2013年5月20日 3:37
  • hello,

    你是否將所有的資料全部讀到TreeView裡了?我並沒有看到你寫出處發子節點展開的代碼

    處理節點前要調用BeginUpdate,然後在調用EndUpdate

    private void InitializeTreeView()
    {
        treeView1.BeginUpdate();
        treeView1.Nodes.Add("Parent");
        treeView1.Nodes[0].Nodes.Add("Child 1");
        treeView1.Nodes[0].Nodes.Add("Child 2");
        treeView1.Nodes[0].Nodes[1].Nodes.Add("Grandchild");
        treeView1.Nodes[0].Nodes[1].Nodes[0].Nodes.Add("Great Grandchild");
        treeView1.EndUpdate();
    }
    實際案例請參考

    http://www.dotblogs.com.tw/yc421206/archive/2009/07/28/9701.aspx
    http://www.dotblogs.com.tw/yc421206/archive/2011/03/12/21808.aspx


    秘訣無它,唯勤而已 http://www.dotblogs.com.tw/yc421206/

    谢谢您的回复,发现您的代码执行的效率很快,确实能立时显示,我修改一下你的代码绑定到数据库试试,绑定到数据库的方式,可以的话能否给我一点提示或代码参考一下?
    2013年5月20日 4:43
  • hi,

    当然,但要把握两个重点

    1.不要一次把所有资料载入

    2.载入资料前调用BeginUpdate,载入完毕后调用EndUpdate


    秘訣無它,唯勤而已 http://www.dotblogs.com.tw/yc421206/

    2013年5月20日 5:18
  • hi,

    当然,但要把握两个重点

    1.不要一次把所有资料载入

    2.载入资料前调用BeginUpdate,载入完毕后调用EndUpdate


    秘訣無它,唯勤而已 http://www.dotblogs.com.tw/yc421206/


    余老师,您好!您能不能给个动态无限级绑定treeview的代码啊,我用foreach了半天都没什么效果。
    2013年5月20日 14:41
  • 感谢各位的指导,我终于搞定了。

    • 已建议为答案 DK. Da 2013年5月31日 7:18
    2013年5月23日 4:03