如何在页面中定义两次页面时避免构造函数被调用两次

时间:2014-05-06 13:27:04

标签: winrt-xaml

我正在创建一个winRt应用。我在其中有一个Home.xaml页面,其中有一个名为Market.xaml的页面。因此对于捕捉模式,重复相同的代码。

现在我的itemListView(用于snapped)和itemGridView(用于完整视图)都有此页面(市场)

<views:Market x:Name="viewMarket"/>

这个页面的构造函数被调用两次,我不想要。

所以我会使用一些旗帜式的东西,或者有更好的方法。

由于

1 个答案:

答案 0 :(得分:0)

所以,让我们谈谈这个:

XAML基本上是C#的不同语法。因此,当XAML引用类似于您的视图的控件时:使用<Views:Market />进行市场营销,您实际上会在两个地方都添加new Views.Market()之类的内容。基本上,两次调用类。如果构造函数不会发射两次,那么时空连续体将分成两半。狗和猫住在一起,整个9码。

但是,更重要的是,C#中的构造函数或XAML类的目的是什么?是不是要做一些你不想重复的昂贵的事情?否。原因是因为在释放UI线程并允许呈现控件之前,必须完成构造函数。结果效果是UI挂起。

此外,C#构造函数是一种同步方法。它无法正确调用或保持异步操作。这意味着应该立即调用的长时间运行或昂贵的任务不应该在构造函数中调用,因为它还需要它们是同步和UI阻塞的。因为最后两点我怀疑你的构造函数被误用了。

解决方案在XAML框架中。 XAML页面管道包含构造函数(因为它是一个C#类,它们都有它)但它还包含一个Loaded事件。在许多情况下,填充页面控件所需的艰苦工作是在Loaded处理程序中。这允许页面正确呈现,然后启动长时间运行的操作,最终和异步更新控件内容。

在WinRT中,Page管道还在基础中包含一个OnNavigatedTo()虚拟方法,您可以覆盖相同的效果。在覆盖中,您可以包括与服务交谈,从文件反序列化或者使UI工作所需的任何内容的艰苦工作。 Loaded事件和覆盖都可以是异步的,并且都不会通过冻结构造函数来阻止渲染。

但是,还有另外一件事要考虑,因为我们在C#中使用了相当常见的模式,称为单例,它允许我们在两个不同的上下文中引用一个类型,但不创建一个全新的类。这是通过使类构造函数为私有来实现的,但是公开一个通常称为Instance的公共属性,该属性在某个静态位置返回单个共享实例。

这可能已经解决了你的问题。再说一次,这些都不是你所需要的。假设您已经知道所有这些,快速回答是您无法阻止构造函数,因为构造函数是创建任何类的新实例化所必需的,包括XAML视图。相反,无论你想要防止双重,都可能需要结合上面的讨论。卸载方法和静态引用以防止重复工作。

这样的事情:

public class Market : UserControl
{
    public Market()
    {
        Loaded += Market_Loaded;
    }

    static bool AlreadyLoaded = false;
    void Market_Loaded(object sender, RoutedEventArgs e)
    {
        if (AlreadyLoaded)
            return;
        AlreadyLoaded = true;
        // TODO: your work
    }
}

但是这可能不适合你,因为静态变量的范围太大。相反,您可以控制是否使用添加到控件的依赖项属性执行大操作。将布尔依赖项属性设置为false,第二个控件知道不执行某些操作。当它设置为true时,第一个知道继续。等等。由于上述解决方案中的静态属性,这可以防止将来在应用程序中使用视图或用户控件时认为它不应该运行。然后,这可能是完美的。

祝你好运!