设置 BindingContext 后调用 Xamarin 表单的 Prism Initialize [英] Prism for Xamarin forms Initialize called after BindingContext is set

查看:64
本文介绍了设置 BindingContext 后调用 Xamarin 表单的 Prism Initialize的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望扩展这里的帖子https://stackoverflow.com/a/60359084/6558112

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

I do not completely understand the sequence of events that happens during view and viewmodel initialization when using Prism. Dan explained this well, but I am still missing something.

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

My scenario is simple, I am passing an ID in the navigation parameters that the viewmodel will use to lookup some data from a service, which is all done in the Initialize method. However, the problem is that the view properties are fired before the Initialize method is called, which means I have no data yet to display, which creates some extra work for me.

Dan 很好地解释了事件的顺序

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

这是我需要帮助的地方:

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

I am assuming that step 3 where Dan says "the Navigation Service will set it for you" means that the view's BindingContext is set at this time? So, the BindingContext is set after the ctor but before the Initialize method? This means that all properties set in the Initialize method will always fire twice, once when the binding is set, and again with the properties are set via Initialize or Autoinitialize?

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

In my case, this is not ideal, since all properties must then be raised in the Initialize method and I have to handle all the null cases.

我真的不想通过选择退出自动装配来手动完成所有操作,但我没有看到任何其他选项,我是否遗漏了什么?有人知道是否可以修改 Prism 以将 BindingContext 的设置延迟到调用 Initialize 方法之后?

I really don't want to do it all manually by opting out of the autowire, but I don't see any other options, am I missing something? Anyone know if it is possible to modify Prism to delay the setting of the BindingContext until after the Initialize method has been called?

谢谢.

推荐答案

Prism 提供的 Initialize 方法:

The Initialize method's offered by Prism:

  • IInitialize.Initialize
  • IIniaializeAsync.InitializeAsync
  • IAutoInitialize

只会被解雇一次.

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

Because the ViewModelLocator is specifically opt-out instead of opt-in there are two ways that it will work.

  1. 您已经在 XAML 中明确设置了 AutowireViewModel 属性,或者您是真正喜欢编码 UI 的人的视图代码.这意味着您的 View 的 BindingContext 将被设置为它的构造函数的一部分.
  2. 您已经让 Prism 的 NavigationService 为您设置了 AutowireViewModel.这意味着 View 的构造函数已经完成.设置属性后,将设置绑定上下文.

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

While I generally use the 2nd method to keep my code cleaner, only explicitly opting-in when there is an edge case that requires it, it ultimately doesn't matter which of the two methods you choose. At this point the constructors of both your View and ViewModel's have executed, and the ViewModel is set as the BindingContext of the View however Prism has not called the Initialize method's.

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

It is only with both the View and ViewModel fully inflated (the constructors having been called and the BindingContext set), that will Prism actually start the initialization process as explained in SO question you referenced: https://stackoverflow.com/a/60359084/6558112

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

Hopefully to make it a bit clearer consider the following comments in the ViewModel below

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...
    }
}

这篇关于设置 BindingContext 后调用 Xamarin 表单的 Prism Initialize的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆