WPF Loaded事件连续调用两次的问题

时间:2021-12-25 21:56:14

最近开发的一套系统中,在检查开发成员的代码时候,在Loaded事件中加上以下语句:

this.Loaded -= new RoutedEventHandler(***_Loaded);这让我觉得有些奇怪。如是参照系统中的代码逻辑写了一个demo。

MainWindow代码如下:

private void Window_Loaded(object sender, RoutedEventArgs e)
{
TabItem item = new TabItem();
UserControl1 test = new UserControl1();
item.Header = "测试。。。";
item.Content = test;
item.IsSelected = true;
tbc.Items.Add(item);
}

UserControl1再加载一个UserControl2,前台代码如下,后台没有代码:

<Grid x:Name="detailGrid">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*"/>
<ColumnDefinition Width="4"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ScrollViewer Grid.Column="2">
<StackPanel>
<my:UserControl2 Margin="3" />
</StackPanel>
</ScrollViewer>

</Grid>

UserControl2 的代码如下:

前台:

<UserControl x:Class="两次Loaded事件.UserControl2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" Loaded="UserControl_Loaded">

<Grid>
<Expander ExpandDirection="Down" IsExpanded="True" x:Name="grpRunInfo">
<Expander.Header>
<TextBlock Text="运行信息"/>
</Expander.Header>
<Expander.Content>
<ScrollViewer Name="scrollViewer1" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<Button Content="第二层" Height="60" Name="button1" Width="123" />
</ScrollViewer>
</Expander.Content>
</Expander>
</Grid>

</UserControl>

后台:

public partial class UserControl2 : UserControl
{
public UserControl2()
{
InitializeComponent();
}

private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
Console.WriteLine("调用uc的loaded");
if (this.IsLoaded)
{
string s = string.Empty;
}
else
{
string b = string.Empty;
}
}
}

就这样简单的一些代码出现了一个奇怪的问题;Usercontrol2的Loaded事件走两次,检查后发现以为是item.IsSelected = true;这句代码让Loaded事件跑了第二遍,其实不然,把这句代码注释掉Usercontrol2的Loaded事件仍然跑两遍。这就头大了,向各群里的同行求助,都没有找到原因或是原因不正确。最后自己挨个检查,发现是Usercontrol1的ScrollViewer控件有问题,把<ScrollViewer Grid.Column="2">这层注释,只留下<StackPanel>这层就不会走两遍UserControl2的Loaded事件。个人理解是不是ScrollViewer加载控件导致UserControl2的Loaded事件走了第二遍,没高人指点就只能这样去理解了。正在这时我把demo发给群里的一哥们有了回复,他说没有我碰到的问题,就只走了一次,这就让我纳闷了,我以为是他没有理解我说的问题或者是我说的问题没有描述清楚。既然我已经知道原因了就没太在意。打算跟开发人员说问题所在并且如何修改。这时候又一之前讨论的人有了回复也说没有碰到我说的问题,他说是不是我的ide有问题,让我重装,我说我用的是vs2010,他说他用的是vs2012;难道是这个原因?又去问前一个说没有碰到问题的人,他也说是用的vs2012。我就问他的编译环境是不是用的.net4.5,他说是4.0;我说我也是用的4.0应该不存在问题的啊;如是我自己下载了一个2013安装并测试,也用的是.net4.0;同样的demo果然没有出现Loaded事件走两次。不理解原因所在,请高手指点。