views:

434

answers:

1

Greetings! Am enjoying using MVVM light -great framework - has made my life much easier, and has removed a number of barriers that were proving difficult to overcome....

Question:

I am attempting to setup a custom dialog box for editing messages users send to each other. I am attempting to construct a silverlight custom dialog box using the ChildWindow object using the MVVM framework.

Was wondering if there were any suggestions as to how this might be accomplished

Following the dialog MVVM sample code I found here: http://mvvmlight.codeplex.com/Thread/View.aspx?ThreadId=209338 I got stuck because the ChildWindow dialog object in Silverlight is async, and has a different Result class.

So - the Basic idea I have now is using the view model of the class (in this case the Matrix.MessageViewModel) to create an instance of the custom dialog box, send it through the Messenger.Send<>, process the registered message in the view to display the dialog, then have the ChildWindow dialog box's Save button handler fire a Messenger.Send with the modified contents that is then stored using the Save method on the viewmodel...

Seems a bit round-about - so wanted to make sure there wasn't a cleaner way....

Relevant code bits:

view model:

messageDialogBox = new MessageEditorDialog(
    selectedMessage, this.SelectedSiteId,  this.LoggedOnEmployee.Id, this.Projects);

DialogMessage editMessage = new DialogMessage(
    this, messageDialogBox,"Edit Message", DialogMessageCallback);
Messenger.Default.Send(editMessage);

View:

public ViewHost()
{
    InitializeComponent();

    Loaded += new RoutedEventHandler(ViewHost_Loaded);

    if (!ViewModelBase.IsInDesignModeStatic)
    {
        // Use MEF To load the View Model
        CompositionInitializer.SatisfyImports(this);
    }

    ApplicationMessages.IsBusyMessage.Register(this, OnIsBusyChange);

    Messenger.Default.Register<DialogMessage>(this, msg => ShowDialog(msg));
}



private void ShowDialog(DialogMessage msg)
{
    MessageEditorDialog myDialog = (MessageEditorDialog) msg.Target;
    myDialog.Show();
}

Dialog Save:

private void ButtonSave_Click(object sender, RoutedEventArgs e)
{
    Messenger.Default.Send<Message>(
        this.MessageItem, CommandMessages.MessageTypes.MessageSave);
}

This ties back into the ViewModel, that has a Messenger.Default.Register<> watching for the CommandTypes.MessageSave which routes the resulting MessageItem to the model for storage.....

+1  A: 

That's pretty darn close to what I'd do, except there are a couple of things I do differently.

  1. I'd have a view model for my dialog view, and move the messaging logic to it rather than the view's code behind.
  2. I'd use a Save command in my view model, and bind the ButtonSave to that command. That moves the save logic to the view model instead of the code behind of your view.
  3. You're using a different message when the save button is clicked. Also, you're not using the DialogMessage's callback. Assuming you change to using a Save command, you could save the message in a private member in the view model, then use message's callback when the user saves.
  4. You may want to think about re-using the dialog view, or ensuring that the view is being cleaned up correctly so you don't end up with a memory leak.

Here's the changes I'd make to your view model following suggestions 2 & 3.

public class MessageEditorDialogViewModel : ViewModelBase
{
    private DialogMessage _dialogMessage;

    public RelayCommand SaveCommand { get; private set; }

    public DialogMessage Message { get; set; }

    public MessageEditorDialogViewModel()
    {
        SaveCommand = new RelayCommand(SaveCommandExecute);
    }

    private SaveCommandExecute()
    {
        Message.Execute();
    }
}
Matt Casto
Excellent thanks! I got the original approach working, but will refactor to yours - I think your suggestions will solve a few other things I have run into...
Mike Morley
@Mike Morley, you should accept this as the answer.
Mike L