Der Aufruf im Viewmodel:
var result = _dialogservice.ShowDialog("Titel für den Dialog", viewmodel4Dialog);
if(result.HasValue && result.Value)
{
}
Damit man diesen Aufruf einfach in einem Viemodel absetzen kann, habe ich folgende Komponenten erstellt. IUIDialogWindowService
/// <summary> /// Interface für das Anzeigen von Dialogen /// </summary> public interface IUIDialogWindowService { ///<summary> /// Zeigt ein Dialog an. ///</summary> ///<param name="titel">Titel für den Dialog</param> ///<param name="datacontext">DataContext für den Dialog</param> ///<returns>true wenn DialogResult=true, ansonsten false</returns> bool? ShowDialog(string titel, object datacontext); ///<summary> /// Zeigt ein Dialog an. ///</summary> ///<param name="titel">Titel für den Dialog</param> ///<param name="datacontext">DataContext für den Dialog</param> ///<param name="minHeigth">Minimum Height</param> ///<param name="minWidth">Minimum Width</param> ///<param name="maxHeigth">Maximum Height</param> ///<param name="maxWidth">Maximum Width</param> ///<returns>true wenn DialogResult=true, ansonsten false</returns> bool? ShowDialog(string titel, object datacontext, double minHeigth = 0, double minWidth=0, double maxHeigth = double.PositiveInfinity, double maxWidth = double.PositiveInfinity); /// <summary> /// Zeigt ein Dialog an /// </summary> /// <param name="titel">Titel für den Dialog<</param> /// <param name="datacontext">DataContext für den Dialog</param> /// <param name="settings">ApplicationsSetting für Height and Width</param> /// <param name="pathHeigthSetting">Name für Height Setting</param> /// <param name="pathWidthSetting">Name für Width Setting</param> /// <param name="minHeigth">Minimum Height</param> /// <param name="minWidth">Minimum Width</param> /// <param name="maxHeigth">Maximum Height</param> /// <param name="maxWidth">Maximum Width</param> /// <returns>true wenn DialogResult=true, ansonsten false</returns> bool? ShowDialog(string titel, object datacontext, ApplicationSettingsBase settings, string pathHeigthSetting, string pathWidthSetting, double minHeigth = 0, double minWidth = 0, double maxHeigth = double.PositiveInfinity, double maxWidth = double.PositiveInfinity);
}
WpfUIDialogWindowService mit MEF Attributen(kann man auch weglassen)
[PartCreationPolicy(CreationPolicy.Shared)] [Export(typeof(IUIDialogWindowService))] public class WpfUIDialogWindowService : IUIDialogWindowService { #region Implementation of IUIDialogWindowService ///<summary> /// Zeigt ein Dialog an. ///</summary> ///<param name="titel">Titel für den Dialog</param> ///<param name="datacontext">DataContext für den Dialog</param> ///<returns>true wenn DialogResult=true, ansonsten false</returns> public bool? ShowDialog(string titel, object datacontext) { var win = new DialogWindow {Title = titel, DataContext = datacontext}; win.Owner = Application.Current.MainWindow; win.ShowInTaskbar = false; return win.ShowDialog(); } ///<summary> /// Zeigt ein Dialog an. ///</summary> ///<param name="titel">Titel für den Dialog</param> ///<param name="datacontext">DataContext für den Dialog</param> ///<param name="minHeigth">Minimum Height</param> ///<param name="minWidth">Minimum Width</param> ///<param name="maxHeigth">Maximum Height</param> ///<param name="maxWidth">Maximum Width</param> ///<returns>true wenn DialogResult=true, ansonsten false</returns> public bool? ShowDialog(string titel, object datacontext, double minHeigth = 0, double minWidth = 0, double maxHeigth = double.PositiveInfinity, double maxWidth = double.PositiveInfinity) { var win = new DialogWindow { Title = titel, DataContext = datacontext }; win.Owner = Application.Current.MainWindow; win.ShowInTaskbar = false; win.MinHeight = minHeigth; win.MinWidth = minWidth; win.MaxHeight = maxHeigth; win.MaxWidth = maxWidth; return win.ShowDialog(); } /// <summary> /// Zeigt ein Dialog an /// </summary> /// <param name="titel">Titel für den Dialog<</param> /// <param name="datacontext">DataContext für den Dialog</param> /// <param name="settings">ApplicationsSetting für Height and Width</param> /// <param name="pathHeigthSetting">Name für Height Setting</param> /// <param name="pathWidthSetting">Name für Width Setting</param> /// <param name="minHeigth">Minimum Height</param> /// <param name="minWidth">Minimum Width</param> /// <param name="maxHeigth">Maximum Height</param> /// <param name="maxWidth">Maximum Width</param> /// <returns>true wenn DialogResult=true, ansonsten false</returns> public bool? ShowDialog(string titel, object datacontext, ApplicationSettingsBase settings, string pathHeigthSetting, string pathWidthSetting, double minHeigth = 0, double minWidth = 0, double maxHeigth = double.PositiveInfinity, double maxWidth = double.PositiveInfinity) { var win = new DialogWindow { Title = titel, DataContext = datacontext }; win.Owner = Application.Current.MainWindow; win.ShowInTaskbar = false; win.MinHeight = minHeigth; win.MinWidth = minWidth; win.MaxHeight = maxHeigth; win.MaxWidth = maxWidth; try { if(settings != null) { win.SizeToContent = SizeToContent.Manual; var height = settings[pathHeigthSetting]; var width = settings[pathWidthSetting]; BindingOperations.SetBinding(win, FrameworkElement.HeightProperty, new Binding(pathHeigthSetting) { Source = settings, Mode = BindingMode.TwoWay }); BindingOperations.SetBinding(win, FrameworkElement.WidthProperty, new Binding(pathWidthSetting) { Source = settings, Mode = BindingMode.TwoWay }); win.Height = (double)height; win.Width = (double)width; } } catch { win.SizeToContent = SizeToContent.WidthAndHeight; } return win.ShowDialog(); } #endregion }Eine Interface um ein DialogResult=true zurück zugeben.
public class RequestCloseDialogEventArgs : EventArgs { public RequestCloseDialogEventArgs(bool dialogresult) { this.DialogResult = dialogresult; } public bool DialogResult { get; set; } } public interface IDialogResultVMHelper { event EventHandler<RequestCloseDialogEventArgs> RequestCloseDialog; }Und damit auch irgendwas angezeigt wird, ein einfaches Fenster zum Anzeigen der Dialoge.
<Window x:Class="DialogWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300" WindowStyle="SingleBorderWindow" WindowStartupLocation="CenterOwner" SizeToContent="WidthAndHeight"> <ContentPresenter x:Name="DialogPresenter" Content="{Binding .}"> </ContentPresenter> </Window>public partial class DialogWindow : Window { //Merken wenn Window geschlossen wurde, damit kein DialogResult mehr gesetzt wird private bool _isClosed = false; public DialogWindow() { InitializeComponent(); this.DialogPresenter.DataContextChanged += DialogPresenterDataContextChanged; this.Closed += DialogWindowClosed; } void DialogWindowClosed(object sender, EventArgs e) { this._isClosed = true; } private void DialogPresenterDataContextChanged(object sender, DependencyPropertyChangedEventArgs e) { var d = e.NewValue as IDialogResultVMHelper; if (d == null) return; d.RequestCloseDialog += new EventHandler<RequestCloseDialogEventArgs>(DialogResultTrueEvent).MakeWeak(eh => d.RequestCloseDialog -= eh); ; } private void DialogResultTrueEvent(object sender, RequestCloseDialogEventArgs eventargs) { //Wichtig damit für ein geschlossenes Window kein DialogResult mehr gesetzt wird //GC räumt Window irgendwann weg und durch MakeWeak fliegt es auch beim IDialogResultVMHelper raus if(_isClosed) return; this.DialogResult = eventargs.DialogResult; } }Damit wäre man jetzt im Prinzip fertig. Jetzt nutzt man einfach die Vorteile von DataTemplates im WPF um ein Viewmodel anzuzeigen. D.h. es muss ein DataTemplate für die entsprechenden DialogViewmodels in den Resourcen (z.b. app.xaml) anlegen.
<DataTemplate DataType="{x:Type viewmodels:TestDialogViewmodel}"> <views:TestDialogView /> </DataTemplate>