1

I have a simple scenario - I have a "UserControl" down inside a WPF app. I want it to raise an event and catch that event at the main window, so I can call "show" to ensure the window is shown (e.g. not hidden in the tray).

I understand from here and here that a RoutedEvent is the way to go.

However, it is complicated because I am using ModernUI as a framework to set up the window. It looks great.

However, in MUI, I just populate "mui:LinkGroup.Links" and the rest of the construction of "pages" is handled for me, so I can't seem to figure out how to refer down the logical tree to actually set up a subscriber to the event. The tree is hidden away in however MUI sets everything up.

So - has anyone done this before? Is there a way I can register a handler for a RoutedEvent using MUI?

Or is there some other way of dealing with events propagated up the tree?

Thanks in advance!

Coopernick
  • 229
  • 2
  • 17

2 Answers2

1

Are you implementing MVVM? In that pattern, if based on a framework like Caliburn Micro or Prism you would use an EventAggregator to create a decoupled notification mechanism. If you are not using any of those frameworks you could search for a stand-alone version of an EventAggregator. But make sure that it uses weak references to keep track of the subscribers. I would definitely prefer that approach toward bubbling events.

[EDIT] For MVVMLight you would use the Messenger class. See Laurents article on MSDN Magazine.

It has a Send Method

Messenger.Default.Send(new AnyMessage());

and a Register method:

Messenger.Default.Register<AnyMessage>(
this,
message =>
{
  // Do something
});
Marius
  • 1,042
  • 1
  • 8
  • 19
  • Yes, I am, very much so. The MVVM Light toolkit. However, that doesn't really solve how to get the parent window to subscribe to the child control's event, when I can't see how to reference the child... – Coopernick Sep 04 '17 at 07:17
  • Re your edit: Huh... I will read that. I watched his video... don't know how I didn't see that. Thanks! – Coopernick Sep 04 '17 at 07:58
  • Ok, I have tried it out and that's the fix. Thanks! – Coopernick Sep 05 '17 at 07:01
1

Just for completeness, and thanks to Marius, here's what I did:

Little message POCO:

class ConnectionStatusChanged
{
    public bool NewStatus;
}

Code sending the message (from background thread in a view model):

Messenger.Default.Send(new ConnectionStatusChanged{NewStatus = '#YOURTRUEFALSEHERE#'});

Messenger receiver (with two lambda delegates, reads a bit ugly):

// Register an MVVM messenger handler to ensure we 
// get any "connection state changed" messages so we can 
// Maximise the window
Messenger.Default.Register<ConnectionStatusChanged>(
    this,
    (status) =>
    {
        // Note dispatcher helper from MVVM - if this occurs
        // we need to use the helper to ensure the "event"
        // fires on the main thread - a background thread trying
        // to manipulate the window will throw an exception.
        DispatcherHelper.CheckBeginInvokeOnUI(
        () => 
        { 
            // Take window out of tray
            Show();
            // Put it on top
            Activate(); 
        });
    });

Note I had to also use the DispatcherHelper as the code that sends the message is not on the main UI thread.

Works great!

Coopernick
  • 229
  • 2
  • 17