Prism for Xamarin 表单在 BindingContext 设置后调用初始化

bmg*_*ith 1 prism xamarin xamarin.forms

我希望在这里扩展这篇文章/sf/answers/4225135911/

我不完全理解使用 Prism 时视图和视图模型初始化期间发生的事件顺序。丹解释得很好,但我仍然遗漏了一些东西。

我的场景很简单,我在导航参数中传递一个 ID,视图模型将使用该 ID 从服务中查找一些数据,这一切都在 Initialize 方法中完成。但是,问题是视图属性在调用 Initialize 方法之前被触发,这意味着我还没有要显示的数据,这给我带来了一些额外的工作。

丹对事件的顺序提供了很好的解释

  1. 视图已创建(视图构造函数中的任何内容都将被执行)
  2. 如果您专门附加了 ViewModelLocator.AutowireViewModel 属性,这会将 ViewModel 解析为构造函数的一部分
  3. 如果您没有明确选择退出 ViewModelLocator 的 Autowire,导航服务将为您设置它(在 ctor 完成后)
  4. 然后,NavigationService 将调用 IAutoInitialize/IInitialize/InitializeAsync(对于 Prism 7.2+...旧版本 Prism 中的 INavigatingAware.OnNavigatingTo)
  5. 然后,导航服务会将页面推送到导航堆栈上(请注意,这可能对用户可见,也可能不可见,因为在深度链接时可能必须首先添加其他页面)
  6. 然后,NavigationService 将调用 OnNavigedFrom / OnNavigedTo (这是人们经常报告由于绑定更新而看到明显延迟的地方。

这是我需要帮助的地方

我假设步骤 3 中 Dan 说的“导航服务将为您设置”意味着此时已设置视图的 BindingContext?那么,BindingContext 是在 ctor 之后但在 Initialize 方法之前设置的吗?这意味着在 Initialize 方法中设置的所有属性将始终触发两次,一次是在设置绑定时触发,另一次是通过 Initialize 或 Autoinitialize 设置属性?

就我而言,这并不理想,因为所有属性都必须在 Initialize 方法中引发,并且我必须处理所有 null 情况。

我真的不想通过选择退出自动连接来手动完成这一切,但我没有看到任何其他选项,我是否遗漏了一些东西?有人知道是否可以修改 Prism 以将 BindingContext 的设置延迟到调用 Initialize 方法之后?

谢谢。

Dan*_* S. 5

Prism提供的Initialize方法:

  • I初始化.初始化
  • IIniaializeAsync.InitializeAsync
  • 自动初始化

只会被解雇一次。

因为 ViewModelLocator 是专门选择退出而不是选择加入,所以它有两种工作方式。

  1. 对于那些真正喜欢编码 UI 的人来说,您已在 XAML 中显式设置了 AutowireViewModel 属性,或者在 View 代码中设置了 AutowireViewModel 属性。这意味着视图的 BindingContext 将被设置为其构造函数的一部分。
  2. 您已经让 Prism 的 NavigationService 为您设置了 AutowireViewModel。这意味着视图的构造函数已经完成。设置该属性后,将设置绑定上下文。

虽然我通常使用第二种方法来保持代码简洁,仅在存在需要它的边缘情况时才显式选择加入,但最终选择两种方法中的哪一种并不重要。此时,View 和 ViewModel 的构造函数都已执行,并且 ViewModel 被设置为 View 的 BindingContext,但 Prism 尚未调用 Initialize 方法。

只有 View 和 ViewModel 完全膨胀(已调用构造函数并设置 BindingContext),Prism 才会真正启动初始化过程,如您引用的问题中所述:https ://stackoverflow.com/a/60359084 /6558112

希望能够更清楚地考虑下面 ViewModel 中的以下注释

public class SampleViewModel : IInitialize, INavigationAware
{
    public SampleViewModel()
    {
        // Called when we inflate the SampleViewModel object
        // This is then added as the BindingContext of the View

        // NOTE: You CAN NOT access Navigation Parameters from here!!!!
    }

    public void Initialize(INavigationParameters parameters)
    {
        // Called before the View (Xamarin.Forms Page) is pushed onto the Navigation Stack
    }

    public void OnNavigatedFrom(INavigationParameters parameters)
    {
        // Called when the View is Navigated away from
    }

    public void OnNavigatedTo(INavigationParameters parameters)
    {
        // Called any time the View is is Navigated to, or back to... 
        // and AFTER Initialize...
    }
}
Run Code Online (Sandbox Code Playgroud)