xamarin.formsmvvmcross

Does mvvmcross have a built-in message for viewmodel to tell view when ViewAppearing/Disappearing happen?


I have logic to be executed in a Xamarin.Forms ContentView (not a Page), when it appears and disappears. This is an mvvmcross content view:

public partial class MyContentView : MvxContentView

I would expect this to be a common need, but I'm not finding a built-in mvvmcross method call or override for this. Is there one? [There was a multiple-year discussion about adding these to Xamarin.Forms itself, but that was never implemented. I was hoping mvvmcross addressed this for views, as they did for their viewmodels.]

NOTE: I'm aware of multiple ways I could roll my own; but surely this is fundamental; built-in?


For completeness, here are the alternatives I'm aware of:

So there are plenty of alternatives. I just feel that I must be overlooking something, since this seems like a common, standard, need. After all, each platform has its own view life-cycle methods. And mvvmcross has corresponding viewmodel life-cycle methods. I'm just trying to get the cross-platform Xamarin.Forms view to have the same life-cycle methods - without inventing my own solution.


Solution

  • The most concise (for the View) solution I've found so far is to add a standard c# EventHandler to my base MvxViewModel. And a property that toggles as viewmodel appears and disappears. Property's setter invokes the event handler.

    viewmodel:

    public class BaseViewModel : MvxViewModel
    {
        // ...
        
        public event EventHandler<BoolEventArgs> AppearingStateEvent;
    
        private bool _AppearingState;
        public bool AppearingState
        {
            get => _AppearingState;
            set
            {
                SetProperty(ref _AppearingState, value);
                AppearingStateEvent?.Invoke(this, new BoolEventArgs(value));
            }
        }
    
        public override void ViewAppearing()
        {
            base.ViewAppearing();
            AppearingState = true;
        }
    
        public override void ViewDisappearing()
        {
            AppearingState=false;
            base.ViewDisappearing();
        }
    }
    

    uses class:

        public class BoolEventArgs : EventArgs
        {
            public bool Value;
            public BoolEventArgs(bool value)
            {
                Value = value;
            }
        }
    

    view:

    public class BaseContentView : MvxContentView
    {
        // ...
        
        protected override void OnBindingContextChanged()
        {
            base.OnBindingContextChanged();
    
            if (ViewModel is BaseViewModel vm)
            {
                // Remove old, in case we get here twice. Avoids duplicate events.
                vm.AppearingStateEvent -= Vm_AppearingStateEvent;
                vm.AppearingStateEvent += Vm_AppearingStateEvent;
            }
        }
    
        protected virtual void Vm_AppearingStateEvent(object sender, BoolEventArgs e)
        {
            bool appearingState = e.Value;
            // ...
        }
    }
    

    View subclasses can override Vm_AppearingStateEvent, to perform actions when view appears or disappears.