【问题标题】:Unable to refresh a xaml Contentpage cleanly with a large amount of items无法用大量项目干净地刷新 xaml 内容页面
【发布时间】:2019-01-22 17:40:05
【问题描述】:

我正在尝试创建一个在应用程序运行时添加日志的日志记录页面。 所需的一项功能是能够自动滚动到最新(最后)添加的日志。

问题是,当我在 observablecollection 上使用 scrollto 功能时,日志记录页面似乎会重新加载整个列表。

这不是问题,但是当列表足够大时,它会导致页面在重绘列表时闪烁。

是否无论如何都向页面添加日志语句并滚动到页面的最后一个元素而不会导致页面闪烁。

我确实支持任何解决方案,但它必须满足以下要求:

  1. 能够在创建/添加日志时实时刷新(频繁)

  2. 能够自动滚动到页面末尾。

  3. 能够干净地刷新(没有闪烁或其他类型的问题)。

我的尝试:

我尝试了两种不同的方法来实现这一点。

第一种方法是将“日志语句”(字符串)的标签添加到 内容页。然后我将使用 lastorDefault() 方法来查找布局中的最后一个子项(在本例中为 stacklayout) 然后滚动到该项目(在本例中为 Label())。

我必须使用 Device.BeginInvokeOnMainThread 将标签添加到主线程(否则它会与程序的其他方面发生冲突)这会导致滚动函数和此调用之间出现竞争条件,最终在列表为足够大。 这种方式的第二个问题是,当页面变得足够大并且我们正在添加语句时,它也会出现闪烁问题。

我尝试实现它的第二种方法是使用可观察集合,在该集合中我将标签添加到可观察集合并使用 用于访问标签文本和文本颜色的数据模板。添加标签后,我使用 scrollto 功能滚动到列表底部。 当列表很小(小于 150 个左右)时,这可以正常工作,但之后添加标签(日志语句)时页面会闪烁。

我目前的想法是在可观察集合中只包含最后 50 个左右的项目,这样刷新就干净了 我正在寻找更好的解决方案,但可能不存在。

我已经对显示的代码进行了大量修改,因此其中一些没有意义,但我已尝试保持此处的逻辑纯净。

我现在无法添加可编译的代码,但如果此代码不足,我将创建一个测试项目,请告诉我。

代码:

    public LoggingPage()
    {
        InitializeComponent();
        loggingPage.ItemAppearing += EnableAutoScroll;
        DisplayLogsOnScreen(logstatements);
    }

    //adds the logs to the screen
    private void DisplayLogsOnScreen(LogStatement logstatements)
    {
        Label loggingLabel = new Label();


        foreach (typeOfLog tempLogType in differentlogTypes)
        {
            switch (tempLogType)
            {
                case typeOfLog.FIRSTTYPE:
                    Device.BeginInvokeOnMainThread(() => {
                        logObservableCollection.Add(loggingLabel);
                    });
                    break;
                case LogType.SECONDTYPE:
                    Device.BeginInvokeOnMainThread(() => {
                        differentLogObservableCollection.Add(loggingLabel);
                    });
                    break;
                default:
                    break;
            }
        }
    }



   // have to wrap the scrollto events in an itemAppeared event handler 
   // otherwise the update to the UI is laggy
   // it still has issues updating the logview this workaround is not perfect

    private void AddAutoScroll(object sender, EventArgs e)
    {
            if (autoScroll)//a button that enables and disables autoscroll
            {
                logListView.ScrollTo(logObservableCollection.LastOrDefault(), ScrollToPosition.End, true);
                logListView.ScrollTo(differentLogObservableCollection.LastOrDefault(), ScrollToPosition.End, true);

            }
    }

Xaml:

<ContentPage Title="logPage">
    <ContentPage.Content>
        <ListView x:Name="loggingPage">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Label Text="{Binding Text}" TextColor="{Binding TextColor}"/>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </ContentPage.Content>
</ContentPage>

【问题讨论】:

    标签: c# .net xaml xamarin xamarin.forms


    【解决方案1】:

    这里的问题是 ListView 的 ScrollTo() 函数。当我们调用时:

                logListView.ScrollTo(logObservableCollection.LastOrDefault(), ScrollToPosition.End, true);
    

    ScrollTo 函数似乎遍历了整个 observable 集合以找到列表中的最后一项。

    我通过创建一个方法而不是使用这个 onAppearing 事件处理程序来规避这个问题。

    这是我更新的代码。请注意,两者都必须在主线程上调用。

           if (statementObject.Types.Contains(LogType.diffLogType))
            {
                Device.BeginInvokeOnMainThread(() => {
                    _incidentLabelListCollection.Add(logStatement);
                    if (autoScroll)
                        EnableAutoScroll(logStatement,null);
                });
            }
    

    第二种方法

        private void EnableAutoScroll(Label label, ListView listView)
        {
            Device.BeginInvokeOnMainThread(() =>
            {
                if(logListView.IsVisible)
                    logListView.ScrollTo(label, ScrollToPosition.End, false);
    
            });
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-17
      • 2012-01-30
      • 1970-01-01
      相关资源
      最近更新 更多