开发者

mvvm light Messenger.Default.Register in View codebehind?

开发者 https://www.devze.com 2023-04-07 12:56 出处:网络
The BookShelf solution John Papa presented at Mix11 has something that sounds a bit odd to me... It uses an MVVM pattern and MVVM Light toolkit... Everything is great.

The BookShelf solution John Papa presented at Mix11 has something that sounds a bit odd to me... It uses an MVVM pattern and MVVM Light toolkit... Everything is great. The only thing I can't understand is this: In codebehind of Views it register for a couple of messages, here it is the code:

public partial class BookView : Page
{
    public BookView()
    {
        InitializeComponent();
        //btnEdit.SetBinding(Button.IsEnabledProperty, new Binding("User.IsAuthenticated") { Source = Application.Current.Resources["WebContext"] });
        Title = ApplicationStrings.HomePageTitle;
        RegisterMessages();
    }

    private void RegisterMessages()
    {
        Messenger.Default.Register<LaunchEditBookMessage>(this, OnLaunchEditBook);
        Mess开发者_JAVA技巧enger.Default.Register<SavedBookDialogMessage>(this, OnSaveBookDialogMessageReceived);
    }

    private void OnLaunchEditBook(LaunchEditBookMessage msg)
    {
        var editBook = new EditBookWindow();
        editBook.Show();
    }

    private void OnSaveBookDialogMessageReceived(SavedBookDialogMessage msg)
    {
        MessageBox.Show(msg.Content, msg.Caption, msg.Button);
    }
//...

It is a business application, if you switch from that Page to another and then come back there, the page gets instanciated again and keeps registering for those messages causing those to fire multiple times...

How comes it subscribe for those messages in codebehind instead of in ViewModels? has this something to do with UI thread? **Is this a correct implementation?

How would you unregister those messages if user navigates to another page?

EDIT: REFACTORED CODE

XAML

<sdk:Page Loaded="Page_Loaded" Unloaded="Page_Unloaded">

CODE BEHIND

private void Page_Loaded(object sender, RoutedEventArgs e)
    {
        RegisterMessages();
    }

    private void Page_Unloaded(object sender, RoutedEventArgs e)
    {
        Messenger.Default.Unregister(this);
    }


Yes, this looks like a bug in his example. He probably isn't expected the page to get instantiated more than once in an application. There is a method for Messenger.Default.Unregister you could hook into on an Unloaded event to fix this issue (you might consider moving the register to Loaded as well.

I understand why he put the events in the View, however. He is opening a new window and calling MessageBox.Show(), since these are very tightly coupled to the View, he kept them in the View. I still don't like the solution personally...

Other MVVM frameworks fight this problem a little better, such as Caliburn. It has lots of helper classes to do View-like things from your ViewModel. Caliburn can 100% eliminate anything in code-behind, but it has a pretty big learning curve.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号