问题:在某些情况下,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事件,能不用则不用。