1

I wrote a small control that creates a popup for my Win8 Phone application which does all the nasty things for me like rotation, proper placement etc. The popup is opened in a Popup control but not on a new phone page. To close the popup, my control hooks up to the "backKeyPressed" event of the underlying page. This works like charm until the underlying page has its own implementation of BackKeyPressed event. In this case, the page event is triggered but not the popup control event.

If I would own the event, I could create my own stack to call the last added event first, but I do not own the event of the pages. As far as I know, I am unable to unregister any previously attached event handler and reassign it once my control unsubscribes from the event.

I could have only one implementation for the BackKeyPressed event which then informs the popup control to close itself (if open), if nothing was open, do the Page specific implementation. But this would require code changes on all pages where I might want to use the popup. Even worse, if I have 5 possible popups, I would have to check all of them :-( So I am looking for an option to handle this centrally.

What other options do I have to overcome this situation?

eX0du5
  • 896
  • 7
  • 16

1 Answers1

0

Normally you cannot change the order of fired events - they are executed in registered order, but it's not required by specifications - source.

But as Jon Skeet says here:

Summary: For all sane events, you can rely on the ordering. In theory, events can do what they like, but I've never seen an event which doesn't maintain the appropriate ordering.

it is fired in registered order and should be.

BUT for your purpose (I think) you can set an event to invoke your method where you would control the order. I think simple example can show this behaviour:

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"); });
    }
}
Community
  • 1
  • 1
Romasz
  • 29,662
  • 13
  • 79
  • 154
  • This would help if I put the code (except the constructor) in a singleton to have one central place for all pages. But then still all pages need to be modified manually. For now I added a stack of open popups to my PopupHelper class which constructs the popup and which handles open / close of them. In the OnBackKeyPressed event of the Page, I call a TryClose() method (static) in the popuphelper. If true, I cancel the back navigation. If the page has no backKeyPressed event, the PopupHelper is also registered to the event. Still I would love to have a way without the page beeing involved :-) – eX0du5 Mar 31 '14 at 15:21
  • @eX0du5 Look that you can also extend your PhoneApplicationPage basing on this code. You can also modify the `add` of your created event so that new handler is added to the top. Also you can provide some methods to change order/sort List. – Romasz Mar 31 '14 at 17:44