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事件,能不用则不用。

原文地址:https://www.cnblogs.com/lnwuyaowei/p/5713822.html