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:
override OnViewModelSet
. But I don't see a corresponding override for the view going away.OnViewModelSet
, could hook up a Binding Set and a Binding or two. To leverage MvxViewModel's lifecycle events. This is my current plan; will add to my BaseView
class. So my inheritance hierarchy becomes MyContentView
: BaseView
: MvxContentView
.MvxMessaging
(or Xamarin.Forms MessageCenter).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.
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.