如何从“设置”弹出窗口中触发页面上的事件

时间:2015-01-05 08:52:17

标签: c# wpf windows-8 windows-runtime winrt-xaml

我正在尝试创建一个Windows Metro App。但目前我无法继续前进,因为我需要有可能触发事件或从主页面上的settingsflyout调用方法。但是我在settingsflyout上没有主页对象,我也不知道如何获得。 有人知道如何做到这一点吗?

1 个答案:

答案 0 :(得分:2)

嗯,首先你应该知道一些技巧。某些事件(如按钮的单击事件)无法以编程方式触发。有一些API调用,例如ShowUI(),它不能从事件处理程序调用,这些调用不是调用堆栈中用户调用的事件的结果。不确定这是否有意义,它只是WinRT中的一件特别的事情。但是,让我们假装您没有尝试调用按钮的Click事件或任何需要用户启动它的API。

有几种方法可以做你想要的。这实际上是一个C#讨论,而不是Windows运行时或XAML讨论。但是,那没关系。这是一个重要问题。

您遇到此问题,因为弹出窗口超出了当前页面的范围。弹出窗口不是页面的子节点,它只是页面调用的东西。弹出窗口中的页面或页面中的弹出按钮没有引用。那我们如何沟通呢?

选项1

您可以在app.xaml.cs中创建一个由弹出窗口引发并由页面处理的公共静态事件。由于外部类不能引发其他类的事件,因此app.xaml.cs还需要一个触发事件的公共静态方法(可由弹出窗口调用)。

有点像这样

public static event EventHandler MyEvent;
public static void RaiseMyEvent()
{
    if (MyEvent != null) MyEvent(null, EventArgs.Empty);
}

这是一个很好的解决方案,因为它可以让弹出窗口与任何调用它的页面进行通信,而无需知道调用它的页面。这意味着两个页面可以调用弹出窗口并且都使用相同的模式对其做出反应。

警告:当您订阅页面中的app.xaml.cs事件时,请不要重复,当您离开页面时不要忘记取消订阅。请记住,垃圾收集不会从内存中删除任何对另一个具有强引用的对象 - 包括事件处理程序。因此,使用+=逻辑,请务必同时包含-=逻辑。 :)

选项2

如果您没有理由从多个页面调用弹出窗口,则可以始终将静态方法放在页面本身上。弹出窗口可以调用此方法并在页面上调用某种类型的操作,而无需引用调用它的实例。只要您没有多个页面实例,这可以正常工作。

选项3

选项2的反面是订阅弹出窗口上的事件。只要您在页面导航时注意取消订阅此事件的警告,就可以这样做了。

  

注意:所有三个选项都可以正常工作。任何人告诉你他们是坏主意只是警告你,他们是你可以轻易搞错的方法类型。如果是我在那之间挑选,我会选择选项1.但是如果你选择选项2或3,我不会认为你犯了一个错误,只是开发者偏好的选择。请记住取消订阅。

选项4

高端方法是使用来自Microsoft的模式和实践的PubSubEvents之类的消息传递服务。我在模块(07) Prism - Part 2中详细描述了这一点。还有MVVM Light中的消息服务,可以使用。这些是事件聚合器,它以抽象的方式完成我在选项1中描述的内容。这并不优越。但它是可重复的,并且不太可能通过强引用来实现。如果这听起来很有趣,那么您可以使用消息服务来完成您在问题中描述的任务。

  

在此处查找模块7:http://blog.jerrynixon.com/2014/10/ready-to-learn-developing-universal.html

选项5 +

当然还有其他方法。您可以在弹出窗口的构造函数中传递页面的引用 - 虽然这很容易出错和误用,但我不推荐它。您可以使用VisualTreeHelper来查看CoreWindow的根元素以查找页面并使用反射调用某些内容。再次,技术上可行,但不推荐,因为它是一堆乱七八糟的代码,很容易出错。

在您的情况下,大多数XAML开发人员只使用静态事件。有些人通过Messaging生活和死亡。我只想做有效的事情。所有这些选项都有效,包括反射疯狂。最终,您的选择是开发人员。只有您了解应用的详细信息。我希望这有帮助。

祝你好运!