我们在我们的应用程序中使用MVVMCross,并且我遇到了一些我不确定我是否已经以最佳方式解决的问题。
我们的ViewModel之一包含3个其他视图模型 - 仪表板和2个列表。在iOS中,这是使用MvxTabBarViewController呈现的,它非常有效。 Android和WP以类似的方式呈现此视图。对象模型的一个例子如下:
public class ProjectViewModel : MvxViewModel
{
public DashboardViewModel Dashboard {get;set;}
public FirstListViewModel FirstList {get;set;}
public SecondListViewModel SecondList {get;set;}
}
我们现在处于这样的情况:如果在DashboardViewModel中发生某个动作,我们想指示导航改变iOS中的选项卡,并在其他平台上发生同样的事情。
我能够在iOS上更改标签的唯一方法是使用this.SelectedIndex = 1;来自iOS ProjectView。
此刻,我设法触发此更改的唯一方法是从DashboardViewModel触发事件,然后ProjectViewModel订阅此事件并触发另一个由ProjectView订阅的事件,以指示它以任何特定于设备的方式更改选项卡。我无能为力,但认为有更好的方法可以做到这一点。
我试过看看自定义ViewPresenter for iOS并从DashboardViewModel中调用ShowViewModel FirstListViewModel,但是演示者似乎没有被使用,所以我们只是正常转换。我的想法是我可以进入中间,取消导航请求,然后翻转ProjectView上的活动标签。
如果我们能够以更好的跨平台方式使用MVVMCross来处理变更,那么任何建议都会受到赞赏。
答案 0 :(得分:2)
您应该可以通过以下几种方式执行此操作:
Show
IMvxInteraction
属性最终,很多这些都可行,我可能会选择哪一个取决于哪一个有效,哪个团队满意 - 运送应用程序始终是最终目标。
鉴于我在MvvmCross的经历,我今天可能会选择尝试尝试自定义IMvxInteraction
属性的方法。但这可能不适合所有人......对于这个样本来说肯定可能矫枉过正 ......
然而,要做到这一点,我会尝试:
public enum Display { Dash, First, Second }
添加到Core项目添加ProjectViewModel
属性:
private MvxInteraction<Display> _display = new MvxInteraction< Display >();
public IMvxInteraction<Display> DisplayChange { get { return _display; } }
每当此ViewModel想要触发更改时,它都可以使用例如_display.Raise(Display.First)
ProjectView
然后可以将Display
绑定到自己的属性,该属性可以实现为:
private IDisposable _subscription;
private IMvxInteraction<Display> _displayInteraction;
public IMvxInteraction<Display> ChangeDisplay
{
get { return _displayInteraction; }
set
{
if (_subscription != null)
{
_subscription.Dispose();
_subscription = null;
}
_displayInteraction = value;
if (_displayInteraction != null)
{
_subscription = _displayInteraction.WeakSubscribe(DoDisplayChange);
}
}
}
private void DoDisplayChange(Display which)
{
// change the tab display here
}
绑定将添加到ViewDidLoad中,如:
set.Bind(this).For(v => v.ChangeDisplay).To(vm => vm.DisplayChange);