The simplest way is to implement a dialogservice and use dependency injection to inject the service into to the viewmodel. It is ok to have a dependency to an interface but not to have a dependency to a concrete implementation.
Following is the interface I use:
namespace DialogServiceInterfaceLibrary
{
public enum MessageBoxButton
{
// Summary:
// The message box displays an OK button.
OK = 0,
//
// Summary:
// The message box displays OK and Cancel buttons.
OKCancel = 1,
//
// Summary:
// The message box displays Yes, No, and Cancel buttons.
YesNoCancel = 3,
//
// Summary:
// The message box displays Yes and No buttons.
YesNo = 4,
}
public enum MessageBoxResult
{
// Summary:
// The message box returns no result.
None = 0,
//
// Summary:
// The result value of the message box is OK.
OK = 1,
//
// Summary:
// The result value of the message box is Cancel.
Cancel = 2,
//
// Summary:
// The result value of the message box is Yes.
Yes = 6,
//
// Summary:
// The result value of the message box is No.
No = 7,
}
// Summary:
// Specifies the icon that is displayed by a message box.
public enum MessageBoxIcon
{
// Summary:
// No icon is displayed.
None = 0,
//
// Summary:
// The message box contains a symbol consisting of white X in a circle with
// a red background.
Error = 16,
//
// Summary:
// The message box contains a symbol consisting of a white X in a circle with
// a red background.
Hand = 16,
//
// Summary:
// The message box contains a symbol consisting of white X in a circle with
// a red background.
Stop = 16,
//
// Summary:
// The message box contains a symbol consisting of a question mark in a circle.
Question = 32,
//
// Summary:
// The message box contains a symbol consisting of an exclamation point in a
// triangle with a yellow background.
Exclamation = 48,
//
// Summary:
// The message box contains a symbol consisting of an exclamation point in a
// triangle with a yellow background.
Warning = 48,
//
// Summary:
// The message box contains a symbol consisting of a lowercase letter i in a
// circle.
Information = 64,
//
// Summary:
// The message box contains a symbol consisting of a lowercase letter i in a
// circle.
Asterisk = 64,
}
public interface IDialogService
{
bool OpenFileDialog(bool checkFileExists,string Filter, out string FileName);
void OpenGenericDialog(object Context,IRegionManager RegionManager);
MessageBoxResult ShowMessageBox(string message, string caption, MessageBoxButton buttons, MessageBoxIcon icon);
}
And the implementation :
public class DialogService : IDialogService
{
public bool OpenFileDialog(bool checkFileExists, string Filter, out string FileName)
{
FileName = "";
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Multiselect = false;
//openFileDialog.Filter = "All Image Files | *.jpg;*.png | All files | *.*";
openFileDialog.Filter = Filter;
openFileDialog.CheckFileExists = checkFileExists;
bool result = ((bool)openFileDialog.ShowDialog());
if (result)
{
FileName = openFileDialog.FileName;
}
return result;
}
public void OpenGenericDialog(object Context,IRegionManager RegionManager)
{
GenericDialogWindow dlg = new GenericDialogWindow(Context,RegionManager);
dlg.Owner = System.Windows.Application.Current.MainWindow;
dlg.Show();
}
public MessageBoxResult ShowMessageBox(string message, string caption, MessageBoxButton buttons, MessageBoxIcon icon)
{
return (DialogServiceInterfaceLibrary.MessageBoxResult)System.Windows.MessageBox.Show(message, caption,
(System.Windows.MessageBoxButton)buttons,
(System.Windows.MessageBoxImage)icon);
}
}
Then inject the IDialogservice into the viewmodel.
The Interface and concrete implementation are typically in a different assembly
MainWindowViewModel(IDialogService dialogservice){
_dialogservice = dialogservice;
}
private void ShowUsercontrol()
{
_dialogservice.ShowMessageBox(... //you get what i mean ;-)
}
The dialogservice is able to open standard windows dialogs like a file open dialog. The generic version can be used as well, but then you need to understand prism which is a bit more complex.
Prism also allows using interaction requests to communicate from the viewmodel to the view. I prefer that way of working in prism, but if you don't know prism forget that remark. It is probably too complex for a simple confirmation window. As simple dialogservice like this is ideal for a simple confirmation window.
Having your dependencies injected via the constructor of the viewmodel, moves you already in the right direction of using a Inversion of control container. And allows for easier unit testing because you can mock the injected interfaces to check if they are called properly and so on.