C#treeview控件的异步更新

穿精又带淫゛_ 提交于 2021-01-15 02:16:33

  在进行Winform程序开发需要进行大量的数据的读写操作的时候,往往会需要一定的时间,然在这个时间段里面,界面ui得不到更新,导致在用户看来界面处于假死的状态,造成了不好的用户体验。所以在大量数据操作的应用上,需要使用多线程来处理这种情况。在c#中使用多线程很方便只需要使用System.Threading.Thread的一个实例的Start方法就行了,但是如何实现多线程之间的交互就不是那么简单。本文实现了用子线程去处理数据,并实时更新主线程的ui状态了。

1、首先要建立一个委托来实现非创建控件的线程更新控件。

2、然后编写多线程去启动写入数据的方法以及回调的函数。

    public partial class ucPrice : UserControl
    {
        SQLiteConnection conn;
        //定义委托
        delegate void inittvItemsDelegate();
        delegate void AsynUpdateUI1(string step);   //更新UI1
        delegate void AsynUpdateUI2(TreeNode root);//更新UI2

        public delegate void UpdateUI(string step);//声明一个更新主线程的委托
        public UpdateUI UpdateUIDelegate;

        public delegate void AccomplishTask(TreeNode root);//声明一个在完成任务时通知主线程的委托
        public AccomplishTask TaskCallBack;

        public ucPrice()
        {
            InitializeComponent();


            twItems.Nodes.Add("正在连接数据库");
            UpdateUIDelegate += UpdataUIStatus;//绑定更新任务状态的委托
            TaskCallBack += Accomplish;//绑定完成任务要调用的委托
            //启动线程
            Thread thread = new Thread(intitvItems);
            thread.IsBackground = true;
            thread.Start();
            //intitvItems();
        }


        //更新UI
        private void UpdataUIStatus(string step)
        {
            if (InvokeRequired)
            {
                this.Invoke(new AsynUpdateUI1(delegate (string s)
                {
                    //this.pgbWrite.Value += s;
                    //this.lblWriteStatus.Text = this.pgbWrite.Value.ToString() + "/" + this.pgbWrite.Maximum.ToString();
                    twItems.Nodes.Add(s);
                }), step);
            }
        }

        //完成任务时需要调用
        private void Accomplish(TreeNode root)
        {
            if (InvokeRequired)
            {
                this.Invoke(new AsynUpdateUI2(delegate (TreeNode rt)
                {
                    //this.pgbWrite.Value += s;
                    //this.lblWriteStatus.Text = this.pgbWrite.Value.ToString() + "/" + this.pgbWrite.Maximum.ToString();
                    twItems.Nodes.Clear();
                    twItems.Nodes.Add(rt);
                }), root);
            }
        }
        private void ucPrice_Load(object sender, System.EventArgs e)
        {
            
        }
        private void  intitvItems()
        {
            TreeNode root = new TreeNode();
            root.Tag = 0;
            root.Text = "物品数据库-"+ "YC122";
            root.Expand();
            //   twItems.Nodes.Add(root);
          try
          {
            conn = new SQLiteConnection("Data Source=db/eve.db;Version=3;");
            conn.Open();

            UpdateUIDelegate("数据库已连接,正在加载数据...");
          }
          catch(Exception ex)
            {
                throw ex;
            }
               

            setTreeView(root, 0);
            UpdateUIDelegate("市场组数据加载完毕,正在加载物品数据");
            setTreeViewLeaf(root);
            UpdateUIDelegate("物品组数据加载完毕.");
            TaskCallBack(root);
            
        }
       /// <summary>
       /// 查找叶子节点
       /// </summary>
       /// <param name="tr1"></param>
        private void setTreeViewLeaf(TreeNode tr1)
        {
           
            foreach(TreeNode node in tr1.Nodes)
            {
                //查找树的叶子节点
                if(node.Nodes.Count==0)
                {
                    addNodeLeaf(node);
                     
                }
                else
                {
                    findTreeViewLeaf(node);
                }
                UpdateUIDelegate("加载物品组"+node.Text);
            }  
        }
        /// <summary>
        /// 第二层遍历,加速函数
        /// </summary>
        /// <param name="tr1"></param>
        private void findTreeViewLeaf(TreeNode tr1)
        {
            foreach (TreeNode node in tr1.Nodes)
            {
                //查找树的叶子节点
                if (node.Nodes.Count == 0)
                {
                    addNodeLeaf(node);

                }
                else
                {
                    flashTreeViewLeaf(node);
                }

            }
        }
        /// <summary>
        /// 第三层遍历,加速函数
        /// </summary>
        /// <param name="node"></param>
        private void flashTreeViewLeaf(TreeNode tr1)
        {
            foreach (TreeNode node in tr1.Nodes)
            {
                //查找树的叶子节点
                if (node.Nodes.Count == 0)
                {
                    addNodeLeaf(node);

                }
                else
                {
                    flashTreeViewLeaf(node);
                }

            }
        }


        /// <summary>
        /// 添加叶子节点
        /// </summary>
        /// <param name="node"></param>
        private void addNodeLeaf(TreeNode node)
        {
            int pid = Convert.ToInt32(node.Tag);

            string sql = "select typeID,typeName_zh from invtypes where marketGroupID="+pid;

            SQLiteDataAdapter reader = new SQLiteDataAdapter(sql, conn);
             
            DataTable dtLeaf = new DataTable();

            reader.Fill(dtLeaf);
            if (dtLeaf.Rows.Count > 0)
            {
                foreach(DataRow dr in dtLeaf.Rows)
                {
                    TreeNode nodeleaf = new TreeNode();
                    nodeleaf.Text = dr[1].ToString();
                    nodeleaf.Tag = Convert.ToInt32(dr[0]);
                
                    node.Nodes.Add(nodeleaf);
                }
            }
        }

        private void setTreeView(TreeNode tr1, int parentId)
        {
            string sql;
            if (parentId == 0)
                sql = "select marketGroupID,marketGroupName_zh,parentGroupID from invmarketgroups where parentGroupID is null";
            else
                sql = "select marketGroupID,marketGroupName_zh,parentGroupID from invmarketgroups where parentGroupID=" + parentId;
            SQLiteDataAdapter reader = new SQLiteDataAdapter(sql, conn);

            DataTable dt = new DataTable();
            reader.Fill(dt);

            if (dt.Rows.Count > 0)
            {
                
                int pId = -1;
                  foreach (DataRow row in dt.Rows)
                  {
                         TreeNode node = new TreeNode();
                         node.Text = row[1].ToString();                     
                         node.Tag =  Convert.ToInt32(row[0]);
                         if (row[2] is System.DBNull)
                            pId = 0;
                         else
                                pId = Convert.ToInt32(row[2]);
                         if (pId == 0)
                          {
                              //添加根节点
                              tr1.Nodes.Add(node);
                          }
                          else
                          {
                              //添加根节点之外的其他节点
                              RefreshChildNode(tr1, node, pId);
                          }
                          //查找以node为父节点的子节点
                          setTreeView(tr1, Convert.ToInt32(node.Tag));
 
                  }
             }
 
         }
        //处理根节点的子节点
        private void RefreshChildNode(TreeNode tr1, TreeNode treeNode, int parentId)
        {
                    foreach (TreeNode node in tr1.Nodes)
                            {
                                if (Convert.ToInt32(node.Tag) == parentId)
                                    {
                                        node.Nodes.Add(treeNode);
                                        return;
                                    }else if (node.Nodes.Count > 0)
                                    {
                                        FindChildNode(node, treeNode, parentId);
                                    }
                            }
            }
 
        //处理根节点的子节点的子节点
        private void FindChildNode(TreeNode tNode, TreeNode treeNode, int parentId)
       {
                   foreach (TreeNode node in tNode.Nodes)
                        {
                              if (Convert.ToInt32(node.Tag) == parentId)
                                 {
                                      node.Nodes.Add(treeNode);
                                     return;
                                 }else if (node.Nodes.Count > 0)
                                 {
                                      FindChildNode(node, treeNode, parentId);
                                  }
       
                     }
   
        }

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!