Displaying user Messages, Errors and Dialogs from a ViewModel using a Service – Part 2

December 18, 2012

no comments

Displaying user Messages, Errors and Dialogs from a ViewModel using a Service – Part 1

In my previous post, I’ve discussed a bit about using the MVVM pattern and how to display a message or opening a dialog from within the view-model.

As part of the discussion, I’ve shown a possible way for displaying Messages, Errors and even Dialog or Popups.

In this post I would like to provide more details about the implementation of the Dialog part.

 

Recall previous post, we have the following two methods of the user interaction service:

 

bool? ShowDialog<TConductor>(string title) where TConductor : IDialogConductor;

 

bool? ShowDialog<TConductor, TParameters>(string title, TParameters parameters)


where TConductor : IDialogConductor<TParameters>;

 

TConductor – implements the IDialogConductor or IDialogConductor<TParameters>. The conductor is responsible for providing the view/view-model pair.

TParameters – an optional parameters can be passed to the dialog view-model. Using this parameters we can pass initial parameters, also get results back when closing the dialog.

 

From here, it’s very simple. Let’s take a look what’s happening inside the service:

 

public
bool? ShowDialog<TConductor, TParameters>(string title, TParameters parameters)


where TConductor : IDialogConductor<TParameters>

{


var conductor = ServiceLocator.Current.GetInstance<TConductor>();


var view = conductor.ResolveView();


var viewModel = conductor.ResolveViewModel(parameters);

 


return ShowDialog(title, view, viewModel);

}

 

private
static
bool? ShowDialog(

string title, DependencyObject view, DialogViewModel viewModel)

{


var element = view as
FrameworkElement;


if (element == null)

{


throw
new
ArgumentException(

“Dialog view must be of type “ + typeof(FrameworkElement).FullName);

}

 

element.DataContext = viewModel;

 


var dialogHost = new
Window

{

Title = title,

SizeToContent = SizeToContent.WidthAndHeight,

Content = element,

};

 


CloseHandler.Create(dialogHost, viewModel);

 


return dialogHost.ShowDialog();

}

 

From what we’re getting here, the process is simple:

  1. Resolve a conductor from a DI container or other.
  2. Use the conductor to resolve the view.
  3. Use the conductor to resolve the view-model.
  4. Now that we have both the view and view-model, connect them together, or let the conductor do that, then display Window, Popup, custom control, etc.

In case that you’re using a DI container, coding is much simpler. To provide a dialog you should:

  1. Create a dialog view and view-model pair.
  2. Create a dialog-specific conductor interface and type and register the type with the container. If you’re using MEF, just decorate it with Export using the relevant IDialogConductor interface as a contract. Also if you’re lazy creating additional conductor type, like I did, let the View be the conductor. So it should implement the IDialogConductor and return itself as the view. Also make sure it’s not Singleton!

 

Here’s an example of the Save Image Dialog types:

///
<summary>

/// Represents the save image dialog conductor interface.

///
</summary>

public
interface
ISaveImageDialog : IDialogConductor<SaveImageDialogParameters>

{

}

///
<summary>

/// Interaction logic for SaveImageDialogView.xaml

///
</summary>

[Export(typeof(ISaveImageDialog)), PartCreationPolicy(CreationPolicy.NonShared)]

public
partial
class
SaveImageDialogView : UserControl, ISaveImageDialog

{


public SaveImageDialogView()

{

InitializeComponent();

}

 


DependencyObject
IDialogConductor<SaveImageDialogParameters>.ResolveView()

{


return
this;

}

 


DialogViewModel
IDialogConductor<SaveImageDialogParameters>.ResolveViewModel(SaveImageDialogParameters parameters)

{


return
new
SaveImageDialogViewModel(parameters);

}

}

///
<summary>

/// The logic of the save image dialog view.

///
</summary>

internal
class
SaveImageDialogViewModel : DialogViewModel

{


private
readonly
SaveImageDialogParameters _parameters;

 


public SaveImageDialogViewModel(SaveImageDialogParameters parameters)

{

_parameters = parameters;

FullPath = _parameters.ImageFilePath;

}

 


public
string FullPath { get; set; }

 


public
DelegateCommandBase CancelCommand

{


get { return GetOrCreateCommand(“CancelCommand”, () => OnClosed(false)); }

}

 


public
DelegateCommandBase SaveCommand

{


get

{


return GetOrCreateCommand(“SaveCommand”, () =>

{

_parameters.ImageFilePath = FullPath;

OnClosed(true);

});

}

}

}

///
<summary>

/// Parameters for the save image dialog.

///
</summary>

public
class
SaveImageDialogParameters

{


public
string ImageFilePath { get; set; }

}

 

I’ve created a small, incomplete, working VS2012 code demonstrating this concept.

Feel free to download it from SkyDrive:

DialogUsingService.rar (http://sdrv.ms/12ynsEK)

Displaying user Messages, Errors and Dialogs from a ViewModel using a Service – Part 1

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*