如何强制某个事件序列

时间:2014-03-31 06:09:29

标签: c# windows-phone-8

我写了一个小控件,为我的Win8 Phone应用程序创建了一个弹出窗口,它为我做了所有讨厌的事情,如旋转,正确放置等。 弹出窗口在弹出控件中打开,但不在新的电话页面上打开。 要关闭弹出窗口,我的控件将连接到底层页面的“backKeyPressed”事件。 这就像魅力一样,直到底层页面有自己的BackKeyPressed事件实现。在这种情况下,会触发页面事件,但不会触发弹出控件事件。

如果我拥有该事件,我可以创建自己的堆栈来首先调用最后添加的事件,但我不拥有页面的事件。 据我所知,我无法取消注册任何以前附加的事件处理程序,并在我的控件取消订阅事件后重新分配它。

我只能为BackKeyPressed事件创建一个实现,然后通知弹出控件关闭自身(如果打开),如果没有打开,则执行Page特定的实现。但是这需要在我可能想要使用弹出窗口的所有页面上进行代码更改。更糟糕的是,如果我有5个可能的弹出窗口,我将不得不检查所有这些:-( 所以我正在寻找一个集中处理这个问题的选择。

我还有什么其他方法可以克服这种情况?

1 个答案:

答案 0 :(得分:0)

通常情况下,您无法更改已触发事件的顺序 - 它们是按注册顺序执行的,但规范并非要求 - source

但是Jon Skeet says here

  

总结:对于所有理智的事件,您可以依赖订购。从理论上讲,事件可以做他们喜欢的事情,但我从未见过一个不能保持适当排序的事件。

按注册顺序触发,应该是。

但为了您的目的(我认为)您可以设置一个事件来调用您控制订单的方法。我认为简单的例子可以显示这种行为:

public partial class MainPage : PhoneApplicationPage
{
    private List<EventHandler<CancelEventArgs>> listOfHandlers = new List<EventHandler<CancelEventArgs>>();

    private void InvokingMethod(object sender, CancelEventArgs e)
    {
        for (int i = 0; i < listOfHandlers.Count; i++) 
            listOfHandlers[i](sender, e);
    }

    public event EventHandler<CancelEventArgs> myBackKeyEvent
    {
        add { listOfHandlers.Add(value); }
        remove { listOfHandlers.Remove(value); }
    }

    public void AddToTop(EventHandler<CancelEventArgs> eventToAdd)
    {
        listOfHandlers.Insert(0, eventToAdd);
    }

    public MainPage()
    {
        InitializeComponent();
        this.BackKeyPress += InvokingMethod;
        myBackKeyEvent += (s, e) => { MessageBox.Show("Added first"); e.Cancel = true; };
        AddToTop((s, e) => { MessageBox.Show("Added later"); });
    }
}