【问题标题】:Implement Lazy Loading of Hierarchical StackLayout in Xamarin Forms在 Xamarin 表单中实现分层 StackLayout 的延迟加载
【发布时间】:2016-09-26 00:05:58
【问题描述】:

TL;DR:我想:

  1. 在每个 StackLayout 中保存一些 c# 对象
  2. 如果用户需要,可以使用来自该对象的信息来呈现另一个 StackLayouts。

详情:

我想将某个网站的所有 Html DOM Tree of Objects 显示为一个列表。

我正在使用 Html Agility Pack 来管理下载的 html。它创建了一个 HtmlNode 对象列表,其中包含一些 HtmlNodes 作为子项、一些 HtmlNodes 作为子项等(就像在 HTML DOM 中一样)。

这是我目前拥有的:

private StackLayout GenerateTreeOfHtmlObjects(HtmlNode htmlNode, int padding)
    {
        StackLayout stackLayout = new StackLayout();
        stackLayout.Orientation = StackOrientation.Vertical;
        foreach (var childNode in htmlNode.ChildNodes)
        {
            if (childNode.Name != "#text")
            {
                Button showMoreButton = new Button { Text = ">", HorizontalOptions = LayoutOptions.Start, };

                stackLayout.Children.Add(
                    new StackLayout
                    {
                        Children = {
                            showMoreButton,
                            new Label { Text = childNode.Name, FontSize=20 },
                            new Label { Text = new string(childNode.InnerText.Trim().ToCharArray().Take(30).ToArray()), FontSize=15 },
                            new Button { Text = "Zaznacz" },
                            GenerateTreeOfHtmlObjects(childNode, padding+10) //RECURSION, CALL THIS FUNCTION AGAIN AS LONG AS THERE ARE SOME CHILDREN
                        },

                        Padding = new Thickness(padding, 0, 0, 10)
                    }
                );
            }
        }
        return stackLayout;
    }

如您所见,我正在为每个 HtmlNode 创建 StackLayout 并为其子级添加另一个 StackLayout。它或多或少可以按我的意愿工作,但问题是它需要太多内存并且加载时间很长

所以我想仅在用户单击其父级时才加载某些 HtmlNode 的子级。我将只加载位于树顶部的那些 HtmlNode,并在需要时依次加载它们的子节点。

为此,我需要在每个 StackLayout 的某处存储一些有关用户点击时加载内容的信息。每个当前加载的 StackLayout 都必须分配 HtmlNode 类,这将允许我加载 HtmlNode 的子级(每个 HtmlNode 都有 ChildNodes 变量,我将从那里获取信息)

【问题讨论】:

  • 您可以使用自己的一些属性(例如类名)创建自定义堆栈布局,然后使用您的属性值来确定它是哪个堆栈布局。
  • 使用 MVVM 模式。然后,您将拥有包含有关视图的所有信息的 ViewModel。见:developer.xamarin.com/guides/xamarin-forms/user-interface/…

标签: c# xamarin xamarin.forms


【解决方案1】:

使用 MVVM 模式。然后,您将拥有包含有关视图的所有信息的 ViewModel。见:https://developer.xamarin.com/guides/xamarin-forms/user-interface/xaml-basics/data_bindings_to_mvvm/

        //// MODEL            
        public class HtmlNode
        {
          public List<HtmlNode> Children{get; set;}
        }

        //// VIEW-MODEL
        public class HtmlTreeViewModel
        {
          public HtmlNode RootNode {get; set;}

          public List<HtmlNode> TreeItems{get; set;}
          ICommand ItemClickedCommand;
          public HtmlTreeViewModel()
          {
           // Get Initial Items
           TreeItems = GenerateTreeOfHtmlObjects(RootNode);
           ItemClickedCommand = new Command(ItemClickCommadFunc);
          }

          private List<HtmlNode> ItemClickCommadFunc(object itemClicked)
          {
              // Fill Children for specific node
              HtmlNode node =(itemClicked as HtmlNode);
              node.Children = GenerateTreeOfHtmlObjects(node);
          }

        }


        //// VIEW
    //This is the datatemplate for each item (you can add name and other stuff)
    //should be defined in resources
    <DataTemplate x:key="NodeTemplate">
       <StackLayout ItemSource="{Binding Children}">
       </StackLayout>
    </DataTemplate>

    //this is the StackLayout that represent the whole tree
    <StackLayout ItemsSource="{Binding RootItem.Children}" ItemTemplate=" StaticResource NodeTemplate}"/>

这只是给你一个想法,你必须自己连接点。不要忘记将 BindingContext 分配给 StackPanel 并在必要时引发 PropertyChanged。

【讨论】:

    猜你喜欢
    • 2016-09-07
    • 1970-01-01
    • 1970-01-01
    • 2021-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多