zoukankan      html  css  js  c++  java
  • Winform复杂界面异步加载

    在加载Winform窗体的时候,有时候我们在窗体里边会有很多复杂的子窗体,特别是由treeView的时候,我们每次切换treeView都需要加载新的窗体,为了更好的用户体验,我们通常在第一次加载窗体的时候就把所有的界面加载完毕,以后切换treeView的时候只需要把需要的窗体bringtofront就可以了,但是过多的窗体加载会使我们第一次加载窗体的时候出现卡顿,这个时候我们就需要使用异步加载。下面使用一个例子来说明:

    image

    这个界面的左侧是12个树节点,当然在右侧会对应12个不同的界面,如果我们按顺序加载,代码应该如下:

    public partial class FormLoadTest : Form 
        { 
            private Dictionary<String, UserControl> dicForms = new Dictionary<String, UserControl>();
    
            public FormLoadTest() 
            { 
                InitializeComponent(); 
            }
    
            private void FormLoadTest_Load(object sender, EventArgs e) 
            { 
                AddControls(); 
                PanelAddControl(); 
                treeView1.SelectedNode = treeView1.Nodes[0]; 
            }
    
            private void AddControls() 
            { 
                string formNames = "UserControl1;UserControl2;UserControl3;UserControl4;UserControl5;UserControl6;UserControl7;UserControl8;UserControl9;UserControl10;UserControl11;UserControl12"; 
                string[] forms = formNames.Split(';'); 
                UserControl control; 
                foreach (string form in forms) 
                { 
                    switch (form) 
                    { 
                        case "UserControl1": 
                            control = new UserControl1(); 
                            break; 
                        case "UserControl2": 
                            control = new UserControl2(); 
                            break; 
                        case "UserControl3": 
                            control = new UserControl3(); 
                            break; 
                        case "UserControl4": 
                            control = new UserControl4(); 
                            break; 
                        case "UserControl5": 
                            control = new UserControl5(); 
                            break; 
                        case "UserControl6": 
                            control = new UserControl6(); 
                            break; 
                        case "UserControl7": 
                            control = new UserControl7(); 
                            break; 
                        case "UserControl8": 
                            control = new UserControl8(); 
                            break; 
                        case "UserControl9": 
                            control = new UserControl9(); 
                            break; 
                        case "UserControl10": 
                            control = new UserControl10(); 
                            break; 
                        case "UserControl11": 
                            control = new UserControl11(); 
                            break; 
                        case "UserControl12": 
                            control = new UserControl12(); 
                            break; 
                        default: 
                            control = new UserControl(); 
                            break; 
                    } 
                    if (!dicForms.ContainsKey(form)) 
                    { 
                        control.Dock = DockStyle.Fill; 
                        dicForms.Add(form, control); 
                    } 
                } 
            }
    
            private void PanelAddControl() 
            { 
                foreach (KeyValuePair<string, UserControl> pair in dicForms) 
                { 
                    if (!splitContainer1.Panel2.Controls.Contains(pair.Value)) 
                    { 
                        splitContainer1.Panel2.Controls.Add(pair.Value); 
                    } 
                } 
            }
    
            private void treeView1_AfterSelect(object sender, TreeViewEventArgs e) 
            { 
                dicForms[treeView1.SelectedNode.Name].BringToFront(); 
            }

    为了更明显的表示问题所在,我们在给个子界面初始化的时候都阻塞了300毫秒。这样,实际加载的时候会加载的很慢,这是我们可以想到,既然界面第一次展示的是树节点的第一个结点,我们只需要加载一个界面就可以了,其他的界面另起一个线程去加载,所以我们在Form_Load的时候只需要调用

    private void AddFirstForm() 
            { 
                UserControl control = new UserControl1(); 
                control.Dock = DockStyle.Fill; 
                dicForms.Add("UserControl1", control); 
                PanelAddControl(); 
                treeView1.SelectedNode = treeView1.Nodes[0]; 
            }
    
    private void FormLoad_Load(object sender, EventArgs e) 
            { 
                AddFirstForm(); 
                Thread thread = new Thread(AddFormsAysnc); 
                thread.Start(); 
                treeView1.Enabled = false; 
            }

    Load里边其他的代码就是去异步加载其他的界面,AddFormsAysnc方法如下:

    private void AddFormsAysnc() 
            { 
                Thread.Sleep(100); 
                MethodInvoker invoke = new MethodInvoker(AddOtherForms); 
                BeginInvoke(invoke); 
            }
    
            private void AddOtherForms() 
            { 
                AddControls(); 
                PanelAddControl(); 
                treeView1.Enabled = true; 
            }

    图中标记的是重点,说是异步加载,其实真正初始化界面的时候还是在主线程进行的,所以我们可以

    Thread.Sleep(100);保证加载其他界面的时候主界面已经出来了

    源代码链接地址 https://files.cnblogs.com/files/sauronKing/FormLoadTest.rar

  • 相关阅读:
    【LeetCode】Validate Binary Search Tree
    【LeetCode】Search in Rotated Sorted Array II(转)
    【LeetCode】Search in Rotated Sorted Array
    【LeetCode】Set Matrix Zeroes
    【LeetCode】Sqrt(x) (转载)
    【LeetCode】Integer to Roman
    贪心算法
    【LeetCode】Best Time to Buy and Sell Stock III
    【LeetCode】Best Time to Buy and Sell Stock II
    CentOS 6 上安装 pip、setuptools
  • 原文地址:https://www.cnblogs.com/sauronKing/p/5488976.html
Copyright © 2011-2022 走看看