Fab*_*ien 9 dialog modal-dialog mvvm mvvmcross
我正在调查所有可能的解决方案,以便能够在需要做出决定时通知用户,即弹出对话框.这是MVVM模式的常见问题,我正在尝试为MvvmCross框架解决它.
可能的解决办法是:
你会建议什么?
Stu*_*art 14
对话输入是一个有趣的主题,并不总是适合Mvvm数据绑定的流程.
通常,Dialog的一些用例适用于以下内容:
对于其中一些项目,我建议主要将这些项目建模为纯粹的View关注点.例如,请求单个项目选择通常来自复合控件标签,这些标签在点击时显示"选择器" - 例如,如https://github.com/slodge/MvvmCross-Tutorials/blob/master/ApiExamples/ApiExamples.Droid中的MvxSpinner /Resources/Layout/Test_Spinner.axml#L16
对于一般情况,你希望共享的ViewModel驱动用户流,那么MvvmCross中可用的选项包括你列出的3个,所有这些对我来说都是可行的,但我同意它们都不是完美的.
作为一个额外的建议,一个很好的架构建议来自微软的模式和实践团队.在http://msdn.microsoft.com/en-us/library/gg405494(v=pandp.40).aspx中,他们提出了一个IInteractionRequest可以在数据绑定中使用的接口,特别是对于这种情况.
他们的参考实现是:
public interface IInteractionRequest
{
event EventHandler<InteractionRequestedEventArgs> Raised;
}
public class InteractionRequestedEventArgs : EventArgs
{
public Action Callback { get; private set; }
public object Context { get; private set; }
public InteractionRequestedEventArgs(object context, Action callback)
{
Context = context;
Callback = callback;
}
}
public class InteractionRequest<T> : IInteractionRequest
{
public event EventHandler<InteractionRequestedEventArgs> Raised;
public void Raise(T context, Action<T> callback)
{
var handler = this.Raised;
if (handler != null)
{
handler(
this,
new InteractionRequestedEventArgs(
context,
() => callback(context)));
}
}
}
Run Code Online (Sandbox Code Playgroud)
ViewModel使用的示例是:
private InteractionRequest<Confirmation> _confirmCancelInteractionRequest = new InteractionRequest<Confirmation>();
public IInteractionRequest ConfirmCancelInteractionRequest
{
get
{
return _confirmCancelInteractionRequest;
}
}
Run Code Online (Sandbox Code Playgroud)
并且ViewModel可以使用以下方法来提升:
_confirmCancelInteractionRequest.Raise(
new Confirmation("Are you sure you wish to cancel?"),
confirmation =>
{
if (confirmation.Confirmed)
{
this.NavigateToQuestionnaireList();
}
});
}
Run Code Online (Sandbox Code Playgroud)
哪个Confirmation是简单的类,如:
public class Confirmation
{
public string Message { get; private set; }
public bool Confirmed { get; set; }
public Confirmation(string message)
{
Message = message;
}
}
Run Code Online (Sandbox Code Playgroud)
在视图中使用它:
MSDN链接显示了Xaml客户端如何使用行为绑定到此 - 所以我不会在这里进一步讨论.
在iOS for MvvmCross中,View对象可能实现如下属性:
private MvxGeneralEventSubscription _confirmationSubscription;
private IInteractionRequest _confirmationInteraction;
public IInteractionRequest ConfirmationInteraction
{
get { return _confirmationInteraction; }
set
{
if (_confirmationInteraction == value)
return;
if (_confirmationSubscription != null)
_confirmationSubscription.Dispose();
_confirmationInteraction = value;
if (_confirmationInteraction != null)
_confirmationSubscription = _confirmationInteraction
.GetType()
.GetEvent("Raised")
.WeakSubscribe(_confirmationInteraction,
DoConfirmation);
}
}
Run Code Online (Sandbox Code Playgroud)
此View属性使用WeakReference基于事件的订阅,以便将ViewModel Raise事件引导到View MessageBox-type方法.使用一个是非常重要的,WeakReference以便ViewModel永远不会引用View- 这些可能会导致Xamarin.iOS中的内存泄漏问题.实际的MessageBox类型方法本身很简单 - 类似于:
private void DoConfirmation(InteractionRequestedEventArgs args)
{
var confirmation = (Confirmation)args.Context;
var alert = new UIAlertView();
alert.Title = "Bazinga";
alert.Message = confirmation.Message;
alert.AddButton("Yes");
alert.AddButton("No");
alert.Clicked += (sender, e) => {
var alertView = sender as UIAlertView;
if (e.ButtonIndex == 0)
{
// YES button
confirmation.Confirmed = true;
}
else if (e.ButtonIndex == 1)
{
// NO button
confirmation.Confirmed = false;
}
args.Callback();
};
}
Run Code Online (Sandbox Code Playgroud)
该属性可以绑定在Fluent Binding集中,如:
set.Bind(this)
.For(v => v.ConfirmationInteraction)
.To(vm => vm.ConfirmCancelInteractionRequest);
Run Code Online (Sandbox Code Playgroud)
对于Android,可以使用类似的实现 - 这可能使用a DialogFragment,也许也可以使用ViewXML内部绑定.
注意:
IInteractionRequest<T>和InteractionRequestedEventArgs<T>定义,基本的交互可以改进(在我看来)- 但是,对于这个答案的范围,我保持'基本'实现保持尽可能接近http中呈现的那个://msdn.microsoft.com/en-us/library/gg405494(v = pandp.40)的.aspx| 归档时间: |
|
| 查看次数: |
10157 次 |
| 最近记录: |