在Xamarin.Forms中处理对象

我正在寻找在Xamarin Forms应用程序中处理对象的正确方法。 目前我正在使用XAML和MVVM编码风格。 然后从我的视图模型中,我通过内置服务定位器( DependencyService )获得对一次性对象的引用。 理想情况下,我应该能够从我的视图模型中调用对象上的Dispose(),但是附加到ContentPage.OnDisappearing和NavigationPage.Popped等其他解决方案也是可行的。

当页面/片段被处理时,当ListViews或Labels的绑定更改值时,我们在Forms中处理了对象exception。 我假设你可以在我们移除绑定的同一个地方处理ViewModel中的对象。

protected override void OnParentSet() { base.OnParentSet(); if (Parent == null) { //Clear a bunch of bindings or dispose of ViewModel objects BindingContext = _listView.ItemsSource = null; } } 

几周前,我的要求几乎相同。 我希望确保在关闭页面时取消订阅视图模型中的事件订阅。 经过大量研究后,我的结论是最简单的解决方案是使用ContentPage.OnDisappearing方法。

当您指出要处置的对象位于ViewModel中时,您需要一些基础结构来确保ViewModel在消失时得到通知。 为此,我定义了我的视图模型的基本实现,它有两个关键方法OnAppearing和OnDisappearing(注意这是一个类而不是一个接口,因为我有其他基本function,如IPropertyNotify实现 – 这里没有显示)。

 public class ViewModelBase { ///  /// Called when page is appearing. ///  public virtual void OnAppearing() { // No default implementation. } ///  /// Called when the view model is disappearing. View Model clean-up should be performed here. ///  public virtual void OnDisappearing() { // No default implementation. } } 

然后我对ContentPage进行了子类化并覆盖OnAppearing和OnDisappearing方法,然后使用它们来通知我的视图模型。

 public class PageBase : ContentPage { ///  /// Performs page clean-up. ///  protected override void OnDisappearing() { base.OnDisappearing(); var viewModel = BindingContext as ViewModelBase; // Inform the view model that it is disappearing so that it can remove event handlers // and perform any other clean-up required.. viewModel?.OnDisappearing(); } protected override void OnAppearing() { // Inform the view model that it is appearing var viewModel = BindingContext as ViewModelBase; // Inform the view model that it is appearing. viewModel?.OnAppearing(); } } 

然后,当您实现页面时,请确保它是PageBase类型:

   

然后,在ViewModel中,您可以覆盖OnDisappearing方法并处理对象:

 public class FormViewModel : ViewModelBase { public override void OnDisappearing() { base.OnDisappearing(); // Dispose whatever objects are neede here } } 

只需要注意一件事 – 如果您正在使用堆栈导航,当您在当前页面上堆叠另一个页面时,会调用OnDisappearing方法(您的页面毕竟会暂时消失)。 因此,您需要满足此要求,并且在这种情况下可能不会丢弃您的对象。 但是,如果您没有在页面顶部堆叠任何内容,则无需担心。 在我的例子中,它只是事件订阅,所以我将事件处理程序附加在OnAppearing中并将它们分离到OnDisappearing上。

我希望能帮到你!

我有符合IDisposable的View模型。 所以我需要一种方法来在不再需要页面时处理Page的BindingContext。

我使用了Nick的建议,当不再需要页面时,使用OnParentSet将其设置为NULL。

可以使用SafeContentPage类代替ContentPage。 Iff绑定上下文支持IDisposable它会自动尝试处理绑定上下文。

 public class SafeContentPage : ContentPage { protected override void OnParentSet() { base.OnParentSet(); if (Parent == null) DisposeBindingContext(); } protected void DisposeBindingContext() { if (BindingContext is IDisposable disposableBindingContext) { disposableBindingContext.Dispose(); BindingContext = null; } } ~SafeContentPage() { DisposeBindingContext(); } } 

OnDisappearing方法不是一种可靠的技术,因为在调用它时存在平台差异,并且仅仅因为页面消失并不意味着不再需要它的视图模型。