Jim Wilcox
Jim Wilcox

Reputation: 1573

MvvmCross View Model Initialize Complete

In version 5 of MvvmCross, there has been added an asynchronous Initialize override where you can do you heavy data loading.

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

Is there a way to determine in the View that the Initialize has completed? Say in the View I want to set the Toolbar Title to a display a field in 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;

    }

On the line that sets the SupportActionBar.Title, is there a way to know for sure whether the Initialize task has completed and if not, get notified when it does?

UPDATE: I tried set two correct answers because @nmilcoff answered my actual question and @Trevor Balcom showed me a better way to do what I wanted.

Upvotes: 3

Views: 899

Answers (3)

boletus151
boletus151

Reputation: 300

On Xamarin Forms: I wanted to add Property Changed event login in the VM to be able to test it, so:

View.xaml.cs

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

    vm.OnViewModelSet();
}

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

Finally on your View Model implement whatever check you need to do for MvvmCross InitializeTask, in my case I used IsCompleted Property, but you can use whichever you need:

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

Don´t forget to unsubscribe, for example when the view is destroyed. You can override this method in your View Model:

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

Upvotes: 2

Trevor Balcom
Trevor Balcom

Reputation: 3888

The Toolbar also supports data binding the Title property like so:

<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" />

Upvotes: 1

nmilcoff
nmilcoff

Reputation: 1084

Yes, you can subscribe to InitializeTask's property changes.

Something like this will work:

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

Of course, it could be the case that it might be easier to just listen to ViewModel.MyObject.Name property changes. But the above is a generic way to listen to InitializeTask property changes.

You can learn more about InitializeTask and MvxNotifyTask in the official documentation.

Upvotes: 6

Related Questions