首页 > 解决方案 > 当xamarin中的应用程序启动时间形成MVVM时如何创建视图模型实例

问题描述

我的目标是访问整个应用程序的可绑定属性。但是我当前的框架 ViewModel 实例创建了多次

我的要求:我在bottomTray(CheckuoutViewModel)中有购物车数量我想在应用页面中的任何位置增加购物车数量,但是在此购物车数量在返回点击时不会更新,它仅适用于前向导航,CheckoutViewModel背后的原因每次都创建实例。这样我就可以尝试更早地进行即时创作。

这里我列出了示例 ViewModel 和调用方法

  1. 登录视图模型
  2. Checkuout ViewModel(此视图模型适用于所有页面)
  3. BaseNavigationViewModel(其 BaseViewModel)

截至目前,我每次都在调用 BindinContext 时,

我试过了

public static ViewModelLocator Locator
    {
        get { return locator ?? (locator = new ViewModelLocator()); }
    }

和 ViewModel 定位器

public ViewModelLocator()
    {
        navigation = App.Current.MainPage.Navigation;
    }
internal CustomTabBarViewModel CustomTabBarVM
    {
        get
        {
            return customTabBarVM ?? (customTabBarVM = new CustomTabBarViewModel(navigation));
        }
    }

和 CustomTabBar.xaml.cs

public CustomTabBar()
    {
        viewModel = App.Locator.CustomTabBarVM;
        InitializeComponent();
        BindingContext = viewModel;
    }

和期望

App.Locator.CustomTabBarVM.BadgeCartCount = OrderObject.Instance.ORDER_OBJECT.Items.Count;

这种方法运行良好,但会产生一些导航问题

标签: xamarin.formsnavigationviewmodelviewmodellocatorbinding-context

解决方案


单例实例是几乎所有 MVVM 框架(Prism、FreshMVVM 等)的共同特征。如果你没有使用框架(如果你没有,我强烈建议你考虑使用一个),下面是一个解决方案。

要获取 ViewModel 的单个实例,您可以使用App该类来托管对象并在需要时访问它。

  • 创建 ViewModel 的公共静态属性:
public static MyViewModel MyViewModelInstance { get; }
  • 在应用程序的构造函数中创建一个实例
public App()
{
    InitializeComponent();

    MyViewModelInstance = new MyViewModel();

    var myPage = new MyPage()
    {
        BindingContext = MyViewModelInstance
    };

    var navPage = new NavigationPage(myPage);

    MainPage = navPage;
}
  • 每当您创建新页面时,访问共享实例
// This method is just an example of how you might create a new page and wire up the view model
async void GoNextClicked(System.Object sender, System.EventArgs e)
{
    var myPage = new MyPage()
    {
        BindingContext = App.MyViewModelInstance
    };

    await this.Navigation.PushAsync(myPage);
}

这种方法有一些注意事项,您是在应用程序加载时创建实例,而不是在需要时创建实例(急切加载)。因此,性能优化将Lazy<T>用于处理这些对象的创建。然而,这是已经在 MVVM 框架中为您编写的逻辑,它们可以帮助您,您应该使用它们。

延迟加载

您可以通过延迟加载视图模型在启动时节省内存和性能,这是重写以支持此模式的示例:

public static MyViewModel MyViewModelInstance
{
    get => _myViewModelInstanceFactory.Value;
}

private static Lazy<MyViewModel> _myViewModelInstanceFactory = new Lazy<MyViewModel>(() => new MyViewModel(), true);

public App()
{
    InitializeComponent();

    var myPage = new MyPage()
    {
        BindingContext = MyViewModelInstance
    };

    var navPage = new NavigationPage(myPage);

    MainPage = navPage;
}

现在这个对象在被你的代码访问之前不会被创建,一旦它被访问,一旦它已经被创建,并且将在你的应用程序生命周期的其余部分继续存在于内存中。


推荐阅读