在带有MVVM的wpf中使用Dialog的好还是不好的做法?

我最近遇到了为wpf应用程序创建添加和编辑对话框的问题。

我想在代码中做的就是这样。(我主要在mvvm中使用viewmodel first方法)

调用对话框窗口的ViewModel:

var result = this.uiDialogService.ShowDialog("Dialogwindow Title", dialogwindowVM);

// Do anything with the dialog result

它是如何工作的?

首先,我创建了一个对话框服务:

public interface IUIWindowDialogService

{

bool? ShowDialog(string title, object datacontext);

}

public class WpfUIWindowDialogService : IUIWindowDialogService

{

public bool? ShowDialog(string title, object datacontext)

{

var win = new WindowDialog();

win.Title = title;

win.DataContext = datacontext;

return win.ShowDialog();

}

}

WindowDialog是一个特殊但简单的窗口。我需要它来保存我的内容:

<Window x:Class="WindowDialog"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

Title="WindowDialog"

WindowStyle="SingleBorderWindow"

WindowStartupLocation="CenterOwner" SizeToContent="WidthAndHeight">

<ContentPresenter x:Name="DialogPresenter" Content="{Binding .}">

</ContentPresenter>

</Window>

wpf中对话框的问题是dialogresult =

true只能在代码中实现。这就是为什么我创建了一个接口dialogviewmodel来实现它的原因。

public class RequestCloseDialogEventArgs : EventArgs

{

public bool DialogResult { get; set; }

public RequestCloseDialogEventArgs(bool dialogresult)

{

this.DialogResult = dialogresult;

}

}

public interface IDialogResultVMHelper

{

event EventHandler<RequestCloseDialogEventArgs> RequestCloseDialog;

}

每当我的ViewModel认为是时候了dialogresult = true,请提出此事件。

public partial class DialogWindow : Window

{

// Note: If the window is closed, it has no DialogResult

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)

{

// Important: Do not set DialogResult for a closed window

// GC clears windows anyways and with MakeWeak it

// closes out with IDialogResultVMHelper

if(_isClosed) return;

this.DialogResult = eventargs.DialogResult;

}

}

现在至少我必须DataTemplate在资源文件(app.xaml或其他内容)中创建一个:

<DataTemplate DataType="{x:Type DialogViewModel:EditOrNewAuswahlItemVM}" >

<DialogView:EditOrNewAuswahlItem/>

</DataTemplate>

好了,我现在可以从我的视图模型调用对话框:

 var result = this.uiDialogService.ShowDialog("Dialogwindow Title", dialogwindowVM);

现在我的问题是,您认为此解决方案有任何问题吗?

编辑:为了完整性。ViewModel应该实现IDialogResultVMHelper,然后可以在OkCommand或类似这样的范围内引发它:

public class MyViewmodel : IDialogResultVMHelper

{

private readonly Lazy<DelegateCommand> _okCommand;

public MyViewmodel()

{

this._okCommand = new Lazy<DelegateCommand>(() =>

new DelegateCommand(() =>

InvokeRequestCloseDialog(

new RequestCloseDialogEventArgs(true)), () =>

YourConditionsGoesHere = true));

}

public ICommand OkCommand

{

get { return this._okCommand.Value; }

}

public event EventHandler<RequestCloseDialogEventArgs> RequestCloseDialog;

private void InvokeRequestCloseDialog(RequestCloseDialogEventArgs e)

{

var handler = RequestCloseDialog;

if (handler != null)

handler(this, e);

}

}

编辑2:我使用此处的代码使EventHandler的注册功能变弱:

http

:

//diditwith.net/2007/03/23/SolvingTheProblemWithEventsWeakEventHandlers.aspx

(网站不再存在,WebArchive

Mirror)

public delegate void UnregisterCallback<TE>(EventHandler<TE> eventHandler) 

where TE : EventArgs;

public interface IWeakEventHandler<TE>

where TE : EventArgs

{

EventHandler<TE> Handler { get; }

}

public class WeakEventHandler<T, TE> : IWeakEventHandler<TE>

where T : class

where TE : EventArgs

{

private delegate void OpenEventHandler(T @this, object sender, TE e);

private readonly WeakReference mTargetRef;

private readonly OpenEventHandler mOpenHandler;

private readonly EventHandler<TE> mHandler;

private UnregisterCallback<TE> mUnregister;

public WeakEventHandler(EventHandler<TE> eventHandler,

UnregisterCallback<TE> unregister)

{

mTargetRef = new WeakReference(eventHandler.Target);

mOpenHandler = (OpenEventHandler)Delegate.CreateDelegate(

typeof(OpenEventHandler),null, eventHandler.Method);

mHandler = Invoke;

mUnregister = unregister;

}

public void Invoke(object sender, TE e)

{

T target = (T)mTargetRef.Target;

if (target != null)

mOpenHandler.Invoke(target, sender, e);

else if (mUnregister != null)

{

mUnregister(mHandler);

mUnregister = null;

}

}

public EventHandler<TE> Handler

{

get { return mHandler; }

}

public static implicit operator EventHandler<TE>(WeakEventHandler<T, TE> weh)

{

return weh.mHandler;

}

}

public static class EventHandlerUtils

{

public static EventHandler<TE> MakeWeak<TE>(this EventHandler<TE> eventHandler,

UnregisterCallback<TE> unregister)

where TE : EventArgs

{

if (eventHandler == null)

throw new ArgumentNullException("eventHandler");

if (eventHandler.Method.IsStatic || eventHandler.Target == null)

throw new ArgumentException("Only instance methods are supported.",

"eventHandler");

var wehType = typeof(WeakEventHandler<,>).MakeGenericType(

eventHandler.Method.DeclaringType, typeof(TE));

var wehConstructor = wehType.GetConstructor(new Type[]

{

typeof(EventHandler<TE>), typeof(UnregisterCallback<TE>)

});

IWeakEventHandler<TE> weh = (IWeakEventHandler<TE>)wehConstructor.Invoke(

new object[] { eventHandler, unregister });

return weh.Handler;

}

}

回答:

这是一个好方法,我过去也使用过类似的方法。去吧!

我绝对要做的一件事是,当您需要在DialogResult中设置“ false”时,使事件接收一个布尔值。

event EventHandler<RequestCloseEventArgs> RequestCloseDialog;

和EventArgs类:

public class RequestCloseEventArgs : EventArgs

{

public RequestCloseEventArgs(bool dialogResult)

{

this.DialogResult = dialogResult;

}

public bool DialogResult { get; private set; }

}

以上是 在带有MVVM的wpf中使用Dialog的好还是不好的做法? 的全部内容, 来源链接: utcz.com/qa/422555.html

回到顶部