【问题标题】:Why is a binding to another ViewModel not opening the corresponding View?为什么绑定到另一个 ViewModel 没有打开对应的 View?
【发布时间】:2018-02-28 20:00:34
【问题描述】:

我正在尝试在一个按钮上设置一个绑定,当单击该按钮时该绑定会导航到一个新的视图模型。

这是我的视图模型:

public class NotificationsViewModel : BaseViewModel
{
    public NotificationsViewModel(IMvxNavigationService navigation)
        : base(navigation)
    {
    }

    public void GoToNextPage()
    {
        _navigation.Navigate<AboutMeViewModel>();
    }

    public MvxCommand GoToNextPageCommand
    {
        get { return new MvxCommand(async () => await _navigation.Navigate<AboutMeViewModel>()); }
    }
}

这是继承自 BaseViewModel 的构造函数(我认为 BaseViewModel 的其余部分不相关,但请告诉我是否有用):

public abstract class BaseViewModel : MvxViewModel, IBaseViewModel
{
    protected readonly IMvxNavigationService _navigation;

    public BaseViewModel(IMvxNavigationService navigation)
    {
        _navigation = navigation;
    }
}

这是我创建与此 ViewModel 的绑定的视图:

public partial class NotificationsView : BaseView<NotificationsViewModel>
{
    public NotificationsView() : base("NotificationsView", null)
    {
    }

    public override void ViewDidLoad()
    {
        base.ViewDidLoad();
        var set = this.CreateBindingSet<NotificationsView, NotificationsViewModel>();
        set.Bind(NextPageButton.Tap()).For(tap => tap.Command).To(nameof(ViewModel.GoToNextPage));
        set.Bind(NextPageCommandButton).To(nameof(ViewModel.GoToNextPageCommand));
        set.Apply();
    }

    public override void DidReceiveMemoryWarning()
    {
        base.DidReceiveMemoryWarning();
        // Release any cached data, images, etc that aren't in use.
    }
}


[Register ("NotificationsView")]
partial class NotificationsView
{
    [Outlet]
    [GeneratedCode ("iOS Designer", "1.0")]
    UIKit.UIButton NextPageButton { get; set; }

    void ReleaseDesignerOutlets ()
    {
        if (NextPageButton != null) {
            NextPageButton.Dispose ();
            NextPageButton = null;
        }
    }
}

这是它继承自的 BaseView:

public abstract class BaseView<T> : MvxViewController<T>, IBaseView
    where T : BaseViewModel
{
    private object _headerToken = null;
    private object _addTaskToken = null;
    private UIView _originalView = null;       

    public BaseView(string name, NSBundle bundle)
        : base(name, bundle)
    {
    }

    public override void ViewDidLoad()
    {
        base.ViewDidLoad();

        if (ViewModel == null)
            return;

        _headerToken = ViewModel.WeakSubscribe(() => ViewModel.IsLogoVisible, OnHeaderEnabledChanged);
        _addTaskToken = ViewModel.WeakSubscribe(() => ViewModel.IsAddTaskVisible, OnAddTaskEnabledChanged);

        ViewModel.Start();
    }
}

当我在模拟器中调试这段代码时,我可以在GoToNextPage 中设置一个断点,这样我就知道绑定正在捕获点击事件。但是,当我继续执行时,不会发生到新视图模型的导航,但不会引发异常。

我能够从另一个页面导航到此视图模型而不会出现问题,因此我认为我设置此绑定的方式一定有问题。据我所知,此绑定的设置与我正在使用的绑定完全相同。我在这里想念什么?

【问题讨论】:

  • 你能发布 BaseView 的定义吗?
  • 是的,已添加 BaseView 定义和 NotificationsView 的其他部分类
  • 您需要绑定到Command。更具体的IMvxAsyncCommand。由于您不使用异步任务来导航您的异常将被吞没。
  • @Martijn00 请查看我所做的更新。我在绑定到 MvxCommand 的视图中添加了另一个按钮,但在该按钮上看到了相同的行为。我是否正确绑定到该 MvxCommand?

标签: c# ios xamarin mvvm mvvmcross


【解决方案1】:

您是否缺少用于注册视图的属性和用于将视图映射到视图模型的属性?

[Register("NotificationsView")] // this is missing...
[MvxViewFor(typeof(NotificationsViewModel))] // this is missing...
public partial class NotificationsView : BaseView<NotificationsViewModel>
{
    public NotificationsView() : base("NotificationsView", null)
    {
    }
}

【讨论】:

  • 感谢您的回答。用于注册视图的属性位于作为视图一部分生成的 NotificationsView.designer.cs 文件中的部分类上。我在我的项目中搜索了将视图映射到视图模型的 MvxViewFor 属性,但在任何地方都找不到它,所以我认为这与我的情况不同。不过我会尝试一下,然后告诉你我发现了什么。
  • 已确认,添加 MvxViewFor 属性并没有改变我的行为。基于this post,在我看来有多种方法可以将视图绑定到 MvvmCross 中的视图模型。
猜你喜欢
  • 2010-10-22
  • 1970-01-01
  • 1970-01-01
  • 2013-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多