在 Xamarin.Forms MvvmCross 中存储视图

Posted

技术标签:

【中文标题】在 Xamarin.Forms MvvmCross 中存储视图【英文标题】:Storing a view in Xamarin.Forms MvvmCross 【发布时间】:2021-12-27 15:43:03 【问题描述】:

我有一个包含四个主要页面的应用程序,通过标签栏切换(没有“后退”按钮)。 一页有很多内容(ScrollView),并且需要几秒钟才能呈现。我通过在工作完成时显示“加载”覆盖来处理这个问题。但是对于那个特定的页面,我想让视图保持活动状态,这样当用户切换到另一个页面并稍后返回时,页面就准备好了,而无需再次加载所有内容。 不过,我不确定如何在 MvvmCross 中做到这一点。

我确实阅读了文档,据我了解,View Presenter 是正确的做法,因为文档说:

“您的应用可以请求的另一种演示文稿更改 提示包括清除/修改 BackStack、更改根 在保持现有观点的同时,……可能性确实是 无止境。您的应用再次成为王者!”

我想我需要为此创建一个自定义 MvxPresentationHint,但我不太明白 :( 我将如何或更确切地说在哪里访问和存储/加载视图?

我通常对 MvvmCross(它是如何工作的)特别是对 Mvx 类的自定义仍然很陌生,尽管我已经使用了一段时间。 任何解释和最好的代码示例超出文档中所写的内容,我们将不胜感激!

【问题讨论】:

任何 MVVM 库的要点在于,您将视图的状态表示为“视图模型”(VM)。那是您定义的一个类,它具有您视图的所有变化细节的属性。因此,您需要保存的是 VM,而不是视图。要恢复,您需要加载该 VM(从您保存它的任何位置)。然后将视图的 BindingContext 设置为该 VM,并按原样重新创建视图。 Google c# mvvm 从视图模型恢复 ui 状态。 感谢您的回答@ToolmakerSteve :) 我已经存储了 VM 以保持状态,但是需要很长时间的元素的绘制,而不是 VM 本身的构建。存储 VM 在这方面没有多大帮助,因为仍然在导航时重新创建视图。我需要的是视图永远不会真正关闭,有点像当你使用“后退”按钮(我认为是从堆栈中拉出)时,但在单击选项卡时做同样的事情。 【参考方案1】:

尝试在 MVVM 中“存储”视图是没有意义的。 XF 视图表示将使用本机(例如“android”或“ios”)小部件创建的内容。创建和测量/布置这些原生小部件是缓慢的。 MVVM View Presenter 不会加速该逻辑。

您需要“保持活力”,而不是“存储”:

对于名为MyPageContentPage,在创建它时,将其存储在静态变量中。 然后重新使用该变量。如果您只需要其中一个,则可以将其存储在类本身中。

修改“后面的代码”,MyPage.xaml.cs

public partial class MyPage : ContentPage

    // Singleton Pattern.
    private static MyPage _it;
    public static MyPage It 
        get 
            if (_it == null)
                _it = new MyPage();
            return _it;
        
    

    // "private", because calling this directly defeats the purpose. Instead, use `MyPage.It`.
    private MyPage()
    
        InitializeComponent();
    

创建它,无论你放在哪里:

new MyPage()

改为:

MyPage.It

例如,您可以使用PushAsync(MyPage.It);

这将始终返回 MyPage 的 SAME INSTANCE。所以一旦它被创建,它就会保持它的状态。

重要提示:请注意,构造函数只调用一次。每次页面出现时需要做的任何代码,放入override .. OnAppearing()方法。

限制:视图在被操作时“期望”成为视觉层次结构的一部分。 如果您尝试更改不在屏幕上的页面或其视图模型,您可能会遇到问题。这些超出了此答案的范围 - 创建一个新的 *** 问题,其中包含您遇到的任何问题的详细信息。

【讨论】:

非常感谢您的回答!我会试试的:) 嗨@ToolmakerSteve,不幸的是,仅静态视图对我不起作用。但是我设法通过将其他页面作为模式打开然后简单地关闭它来保持它的活力,因此它在激活时类似于后退导航。但我确实有问题,绑定丢失了。一旦视图消失并重新出现,RaiseProperty() 将不再起作用。你有什么想法可以解决这个问题吗? 这也发生在“WrapInNavigationPage”属性中,顺便说一句。 @Laila - 最好提出一个关于丢失绑定的新问题。您需要显示所有涉及的代码,以便有人弄清楚。我没用过 MvvmCross,所以不确定。

以上是关于在 Xamarin.Forms MvvmCross 中存储视图的主要内容,如果未能解决你的问题,请参考以下文章

在 Xamarin.Forms MvvmCross 中存储视图

如何将 Xamarin Forms Shell 集成到 MvvmCross 设置中

如何将 Xamarin Forms Shell 集成到 MvvmCross 设置中

MvvmCross 与 Xamarin.Forms 和自定义 iOS 渲染器 - 防止导航滑动 iOS - MasterDetail

Xamarin Forms MvvM框架之FreshMvvM翻译一

是否有mvvmcross提供的标签式布局平台?