• WPF中USER控件的LOADED事件陷阱


    问题:在某些情况下,WPF中的自定义用户控件中的LOADED事件会执行两次,典型问题是在TabControl中动态加入TabItem,再加入UserControl,比如代码如下:

    UserControl1 uc = new UserControl1();
    
    TabItem tab = new TabItem();
    tab.Header = "test";
    tab.Content = uc;
    this.tabControl.Items.Add(tab);
    

      

    此时,如果在UserControl1中的Loaded事件中加入Message测试,则在创建时引发一次,而在Focus时又引发一次,这个也可以说不是一个Bug,因为每次Focus时都会引发此事件。但问题是,当遇见如下代码,则会引起一个很奇怪的错误:

     public partial class UserControl1 : UserControl
        {
            public Test test = null;
            public UserControl1()
            {
                InitializeComponent();
            }
    
            private void UserControl_Loaded(object sender, RoutedEventArgs e)
            {
                if (test == null)
                {
                    test = new Test();
                    //test.testString = "testString";
                }
                else
                {
                    test = null;
                }
    
                this.DataContext = test;
                //this.grd.ItemsSource = test.testList;
                MessageBox.Show("Proc");
            }
    
            private void button_Click(object sender, RoutedEventArgs e)
            {
                if (test == null)
                {
                    MessageBox.Show("null");
                }
                else
                {
                    MessageBox.Show(test.testString);
                }
            }
        }
        public class Test
        {
            public string testString = null;
            public List<string> testList = null;
        }
    

      注意:在Click事件中,test为Null。

          当然没有人会这样写代码,但是在一些应用中,比如数据库应用,这样的代码会非常的容易出现,比如:

       if (test == null)
                {
                    test = new Test();
                    //test.testString = "testString";
                }
                else
                {
                    //加载数据,test可能为null
                    test = DB.SameTable.SingleOrDefault.........
                }
    
                this.DataContext = test;
                //this.grd.ItemsSource = test.testList;
                MessageBox.Show("Proc");
    }
    

      此时,(由于编译器版本不同原因,不同的的版本会得到不同的test,有的版本为null,有的版本为非null,依据是否执行两次Loaded事件而定,测试环境:VS2015),在Loaded事件中所写的代码,可能会有不同的表现,所以得出最后结论:Loaded事件,能不用则不用。

  • 相关阅读:
    UVa
    UVa
    USACO
    USACO
    USACO
    Floyed算法学习
    POJ
    POJ
    codeforces 796C Bank Hacking
    codeforces 796B Find The Bone
  • 原文地址:https://www.cnblogs.com/lnwuyaowei/p/5713822.html
Copyright © 2020-2023  润新知