MvvmCross视图模型初始化完成

时间:2017-12-01 17:04:10

标签: c# xamarin mvvmcross

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

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

有没有办法在View中确定Initialize已经完成?在视图中说我想将工具栏标题设置为在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向我展示了一个更好的方法来做我想要的。

3 个答案:

答案 0 :(得分:5)

是的,您可以订阅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

答案 1 :(得分:2)

在Xamarin形式上: 我想在VM中添加“属性更改”事件登录名以便能够对其进行测试,所以:

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;
}

答案 2 :(得分:1)

工具栏还支持绑定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" />