2010-08-06 163 views
28

要在WPF中实现基于选项卡的环境,我们需要将我们的WPF表单转换为用户控件以完成基于标签的环境,但是当执行此操作时,用户控件的loaded event被称为two times加载的WPF用户控件触发两次

在互联网上搜索时,其他人也指出了这个问题。我们如何才能确保加载的事件只被调用一次,因为当多次调用它时,多次调用控件的初始化。

感谢

+0

我试着在一个空的.NET 4.0 WPF应用程序中重现这一点,并且Loaded事件只触发了一次。你有没有尝试看看调用堆栈,看看是否可能在.NET Framework中发生奇怪的事情,然后触发Loaded事件? – 2011-02-25 23:07:01

+0

将您的用户控件放在选项卡控件中,切换选项卡时您将能够重现该问题。 – Eternal21 2013-04-10 14:49:37

回答

36

在本blog解释,Loaded事件被触发时,曾经控制即将被渲染(即被添加到视觉树中)。

有几个控件会导致您的控件被加载/卸载多次。例如,本机WPF TabControl仅呈现选定选项卡的内容。所以当你选择一个新的标签时,先前选择的标签的内容被卸载。如果你点击回到先前选择的标签,那么它的内容被重新加载。

一个解决方法是使用布尔值标记您是否已经初始化您的控件,正如其他人所建议的那样。或者,您也可以使用Initialized事件。

+0

我使用TabControl的'ItemsSource'来绑定多个选项卡,并使用'DataTemplate'将ViewModel绑定到选项卡视图。在我的情况下,不仅'Loaded'事件再次被触发,而且标签视图的构造函数**也被再次调用。看来WPF每次切换选项卡都会完全重新创建我的选项卡控件。 – Felix 2017-03-30 10:44:18

2

事件设置一个loaded标志,并且,如果标志已经设置,没有做任何事情。

+0

感谢您的建议,这真的是一个真正的问题,并且由于选项卡 – 2010-08-06 05:59:26

-3

事实上,已经有一个IsLoaded属性,因此您可以将此行添加到加载事件处理程序的开头:

If Me.IsLoaded Then Return 
+2

被称为两次加载事件没关系,这是行不通的。你必须使用自己的财产。 – 2010-08-16 02:36:09

+7

你应该删除你的答案,保持干净。 – DuckMaestro 2014-10-06 23:52:54

+1

在Loaded事件处理程序中,很明显,IsLoaded属性始终为true。 – Pejman 2016-10-02 15:14:38

11

您的路由事件处理程序可以(也应该)从Loaded钩子中移除它作为第一件事。

public class MyClass : Window 
{ 
    public MyClass() 
    { 
     Loaded += MyLoadedRoutedEventHandler; 
    } 

    void MyLoadedRoutedEventHandler(Object sender, RoutedEventArgs e) 
    { 
     Loaded -= MyLoadedRoutedEventHandler; 
     /// ... 
    } 
};