WindowsPhoneMVP - Sending Events to the Presenter

The MVP pattern allows for a lot of flexibility when developing Applications, in terms of if you need to invoke something in the view or on the model then you have that option. However, one downside to the way Presenters are wired up to Views means there is a lot of 'mess' around creating events in an IView interface, calling the event from the View implementation and also and subscribing to events from the Presenter.

When using MVP with WindowsPhone/Silverlight you have the option (and more so in WindowsPhone 7.1) of Commanding by the use of such things as RelayCommands/Delegate Commands. This lessens the need to create and subscribe to events everywhere, but currently command support does not cover everything we'd like it to, so here's another option.

I've been looking at ways by using attached properties in XAML to invoke a method on the presenter. The following is what feels like it's starting to go somewhere. In its simplest form, the following attached property can invoke a method "ToViewTwo()" on the corresponding presenter:

<Button Content="View Two" Name="ToViewTwo" cmd:ItemToPresenter.Event="Click" />

But usually you'll want to pass some parameters in, the parameter system can work with the following options:

<Button Content="View Two" Name="ToViewTwo" 
cmd:ItemToPresenter.Event="Click($sender$, $args$, {Binding MyProperty})" />
  • $sender$ - a named variable for the element that created the event.
  • $args$ - a named variable that will pass through the event arguments, this will change depending on the event you subscribe to. In the case of this button click you will receive a RoutedEventArgument, if you subscribed to "DoubleTap" you would receive a GestureEventArguement.
  • {Binding} {Binding Property} - Will resolve the specified property value from the DataContext.
  • Any property of element can also be used as a parameter.

The reason I think this kind of idea is reasonably powerful and flexible is that as mentioned above, when WindowsPhone7.1 comes along, we'll get a bunch more new events across our visual elements, which means we'll be able to use them instantly like so:

<Button Content="View Two" Name="ToViewTwo" cmd:ItemToPresenter.Event="DoubleTap($args$)" />

The ApplicationBar

The ApplicationBar as far as I'm concerned as never been 'nice' to use. The reason probably resides in the fact that it lies outside the visual element tree of the current application page. So because of this, it needs to be dealt with as a special case but generally the same as above can be applied.

<shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png" 
Text="Button 1" cmd:ItemToPresenter.IconButton="AppBarItemClicked_Click($sender$, $args$)"  />
  • AppBarItemClicked_Click - To override the method name that will be called on the presenter, the event can be prefixed with that name. In this case the AppBarItemClicked will be called on the Presenter and the $sender$ and $args$ parameters will be passed in.

Menu items are also supported in the same way:

<shell:ApplicationBarMenuItem Text="MenuItem 1"
cmd:ItemToPresenter.MenuItem="AppBarItemClicked_Click($sender$)" />

I currently like the idea here and somewhat the direction it's heading, however I don't feel totally solid on the syntax. By all means I'd love to hear suggestions on how things can feel more usable, or other features that might be good to have.

The sourcecode for this is currently sitting in the WindowsPhoneMVP repository if you want to have an early look.

WP7 WindowsPhoneMvp
Posted by: Brendan Kowitz
Last revised: 21 Sep 2013 12:13PM

Comments

No comments yet. Be the first!

No new comments are allowed on this post.