OnNavigatedTo或初始化得太晚而无法绑定

问题描述 投票:0回答:1

我是Xamarin.Forms的Prism新手。我已经使用Navigation和Commanding类实现了ViewModel方法。它工作正常,但只有一件事我不明白。将AutowireViewModel设置为true时,ViewModelLocator会自动为我填充BindingContext,这很不错。事情的顺序不是我所期望的。首先,对View上的属性进行绑定,然后触发OnNavigatedTo。这意味着我在View上收到参数时,属性的初始化已经完成。我可以通过执行RaisePropertyChanged解决此问题。这将导致以下情况:

  1. 我被迫为要在ViewModel上使用新数据在视图上看到的每个属性编写RaisePropertyChanged。
  2. 所有绑定均触发两次。对于快速的东西来说,这不是问题,但有些速度较慢。
  3. 视图变为可见后刷新数据。不会打扰,但最好一次显示完整的视图及其数据。
  4. 所有属性必须能够处理空引用。

在绑定开始之前,有没有一种方法可以在ViewModel中初始化数据?

xamarin.forms prism
1个回答
0
投票

实际上是Xamarin.Forms的Prism,长期以来一直支持在将View推送到NavigationStack之前初始化ViewModel。也就是说,必须考虑操作顺序。例如,我们无法对ViewModel执行一堆操作,然后将其附加到View。

执行操作的顺序如下:

  • 创建视图(执行视图ctor中的所有操作)
  • 如果您专门附加了ViewModelLocator.AutowireViewModel属性,这将把ViewModel解析为ctor的一部分
  • 如果您没有特别选择退出ViewModelLocator的自动装配,导航服务将为您设置它(在ctor完成之后)
  • 然后,导航服务将调用IAutoInitialize / IInitialize / InitializeAsync(对于Prism 7.2 + ... inavigatingAware.OnNavigatingTo,在较旧的Prism中)
  • 然后,NavigationService将页面推送到导航堆栈上(请注意,这可能对用户不可见,因为在进行深度链接时可能必须先添加其他页面)
  • 然后NavigationService将调用OnNavigatedFrom / OnNavigatedTo(这是人们经常报告由于绑定更新而看到的可见延迟的地方。

对于绝大多数情况,如果您已正确初始化ViewModel,则此过程完全可以根据需要进行。如果在某些极端情况下必须绝对确保在设置ViewModel之前对其进行初始化,那么您将需要手动进行处理。

public partial class ViewA : ContentPage, IInitialize
{
    private ViewAViewModel ViewModel { get; }

    public ViewA(ViewAViewModel viewModel)
    {
        ViewModel = viewModel;

        // Explicitly Opt Out of Autowiring
        ViewModelLocator.SetAutowireViewModel(this, false);

        InitializeComponent();
    }

    public void Initialize(INavigationParameters parameters)
    {
        ViewModel.Initialize(parameters);
        BindingContext = ViewModel;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.