【问题标题】:MvvmCross View Model Initialize CompleteMvvmCross View 模型初始化完成
【发布时间】:2017-12-01 17:04:10
【问题描述】:

在 MvvmCross 的第 5 版中,添加了一个异步初始化覆盖,您可以在其中进行大量数据加载。

public override async Task Initialize()
{
    MyObject = await GetObject();
}

有没有办法在视图中确定初始化已完成?在视图中说我想将工具栏标题设置为在 MyObject 中显示一个字段

    MyViewModel vm;

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);

        // Create your application here

        this.SetContentView(Resource.Layout.MyView);

        var toolbar = (Toolbar)FindViewById(Resource.Id.toolbar);
        SetSupportActionBar(toolbar);

        vm = (MyViewModel)this.ViewModel;

        SupportActionBar.Title = vm.MyObject.Name;

    }

在设置 SupportActionBar.Title 的行上,有没有办法确定 Initialize 任务是否已完成,如果未完成,则在完成时收到通知?

更新: 我尝试设置两个正确答案,因为@nmilcoff 回答了我的实际问题,@Trevor Balcom 向我展示了一种更好的方法来做我想做的事。

【问题讨论】:

    标签: c# xamarin mvvmcross


    【解决方案1】:

    是的,您可以订阅 InitializeTask 的属性更改。

    这样的事情会起作用:

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
    
        // your code
    
        ViewModel.PropertyChanged += MyViewModel_PropertyChanged;
    }
    
    private void MyViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if(e.PropertyName == nameof(ViewModel.InitializeTask) && ViewModel.InitializeTask != null)
        {
            ViewModel.InitializeTask.PropertyChanged += ViewModel_InitializeTask_PropertyChanged;
        }
    }
    
    private void ViewModel_InitializeTask_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if(e.PropertyName == nameof(ViewModel.InitializeTask.IsSuccessfullyCompleted))
            SupportActionBar.Title = ViewModel.MyObject.Name;
    }
    

    当然,听ViewModel.MyObject.Name 属性更改可能更容易。但上面是监听 InitializeTask 属性变化的通用方式。

    您可以在official documentation 中了解有关InitializeTaskMvxNotifyTask 的更多信息。

    【讨论】:

    • 我以前尝试过这种方法,但问题是 Initialize() 在您挂钩 PropertyChanged 事件之前被调用,如果它在您挂钩事件之前完成,您的事件处理程序永远不会收到通知。我看过 MvxNotifyTask 但它没有说明如何连接它来收听 Initialize() 任务。我会看看 InitializeTask 看看这是否可能是答案。
    • 我没有看到 ViewModel 上有一个名为 InitializeTask 的属性。
    • 没关系。我必须更新到最新版本的 MvvmCross。
    • 确实如此。谢谢兄弟。
    【解决方案2】:

    在 Xamarin 表单上: 我想在 VM 中添加 Property Changed 事件登录以便能够对其进行测试,所以:

    View.xaml.cs

    protected override void OnViewModelSet()
    {
        base.OnViewModelSet();
        var vm = this.DataContext as SearchMovieViewModel;
        if (vm is null)
        {
            return;
        }
    
        vm.OnViewModelSet();
    }
    

    在您的 ViewModel 上:

    /// <summary>
    /// This method should be called in every View Code Behind when you
    /// need to subscribe to InitializeTask changes.
    /// </summary>
    public void OnViewModelSet()
    {
        if (this.InitializeTask is null)
        {
            return;
        }
        this.InitializeTask.PropertyChanged += this.InitializeTask_PropertyChanged;
    }
    

    最后在你的视图模型上实现你需要对 MvvmCross InitializeTask 做的任何检查,在我的例子中,我使用了 IsCompleted 属性,但是你可以使用任何你需要的东西:

    private void InitializeTask_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == nameof(this.InitializeTask.IsCompleted))
        {
            // do something
        }
    }
    

    不要忘记取消订阅,例如当视图被销毁时。您可以在视图模型中覆盖此方法:

    public override void ViewDestroy(bool viewFinishing = true)
    {
            base.ViewDestroy(viewFinishing);
            this.InitializeTask.PropertyChanged -= this.InitializeTask_PropertyChanged;
    }
    

    【讨论】:

      【解决方案3】:

      工具栏还支持数据绑定Title 属性,如下所示:

      <android.support.v7.widget.Toolbar
          android:id="@+id/toolbar"
          android:layout_width="match_parent"
          android:layout_height="?attr/actionBarSize"
          app:popupTheme="@style/AppTheme.PopupOverlay"
          app:MvxBind="Title MyObject.Name" />
      

      【讨论】:

      • 这是一种更好的方式来做我想做的事情。它不会让我设置一个正确的答案,所以我必须选择一个回答实际问题的答案。我正在浏览我的代码并使用您的方法为所有内容设置标题。谢谢兄弟。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-11-26
      • 1970-01-01
      • 2013-03-12
      • 2011-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多