問題:在某些情況下,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事件,能不用則不用。
