WPF - using modernUI - how can I set up a RoutedEvent generated from a user control?

168 views Asked by At

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!

2

There are 2 answers

3
Marius On BEST ANSWER

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
});
0
Coopernick On

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!