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);保證加載其他界面的時候主界面已經出來了

源代碼鏈接地址 http://files.cnblogs.com/files/sauronKing/FormLoadTest.rar


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM