Help us understand the problem. What is going on with this article?

Xamarin.Formsでページが破棄されたタイミングでViewModelのDisposeなどを実行する

More than 3 years have passed since last update.

Xamarin.FormsでViewModelを使っている場合、そのページが破棄されたタイミングでイベントの購読解除等を行うDispose的な処理を書きたいなと思っていてその方法を調べてみました。
ページが破棄されるのをStackからページがPopされることとすれば、Popに関するイベントを捉えるのが良さそうです。
調べてみるとPushAsyncはNavigationPageのPoppedイベント、PushModalAsyncはApplication.CurrentのModalPoppedイベントで対処できるようです。

ViewModelに適当なインターフェースを適用する

例としてIDisposableを適用。自作インターフェースでももちろん可。

public class ViewModelSample : IDisposable
{
    public void Dispose(){
        //後始末
    }
}

NavigationPageのPoppedに登録

PopAsyncでPopしたページはNavigationPageのPoppedイベントで拾えるのでNavigationPageのコンストラクタ等で処理を登録しておきます。毎回書くのがめんどうならBaseクラスにでも。

public MainNavi() {
    this.Popped += (sender, e) => {      
        (e.Page.BindingContext as IDisposable)?.Dispose();
    };
}

Application.CurrentのModalPoppedに登録

PopModalAsyncでPopしたページはApplication.CurrentのModalPoppedイベントで拾えるのでAppクラスのコンストラクタ等で処理を登録しておきます。

public App(){
    Application.Current.ModalPopped = (sender, e) => {
        (e.Modal.BindingContext as IDisposable)?.Dispose();
    };
}

注意事項

PopToRootAsyncを使うと処理対象のページを見失います。
PoppedToRootイベントで拾えそうなんですが、そこで拾えるのは直前のページだけで他のページは参照できません。しかもPoppedToRootはPopした後なのでNavigationStackにも残ってません。なのでPopと特定の処理を合わせたい場合はPopToRooTAsyncは使わないようにするか、同様の動きをする機能を独自に実装するしかないと思います。

補足

iOSではTabbedPageの現在表示中のタブをクリックするとルートページに戻ります。これはPopToRootしているように見えますが実際は1ページずつPopしているようなのでPoppedイベントの方で処理できます。

参考

https://forums.xamarin.com/discussion/57043/viewmodels-not-disposing-on-navigation-pop

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした