gpt4 book ai didi

c# - 无法使用大量项目干净地刷新 xaml 内容页面

转载 作者:太空宇宙 更新时间:2023-11-03 14:50:50 24 4
gpt4 key购买 nike

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

问题是,当我在 observablecollection 上使用 scrollto 函数时,日志页面似乎重新加载了整个列表。

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

有没有向页面添加日志语句并滚动到页面的最后一个元素而不导致页面闪烁的方法。

我真的愿意接受任何解决方案,但它必须满足以下要求:

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

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

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

我的尝试:

我尝试了两种不同的方法来实现它。

第一种方法是将“logstatement”(字符串)标签添加到内容页。然后我会使用 lastorDefault() 方法找到布局中的最后一个 child (在本例中为 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>

最佳答案

这里的问题是 ListView 的 ScrollTo() 函数。当我们打电话时:

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

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

我通过创建一个方法而不是使用这个 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);

});
}

关于c# - 无法使用大量项目干净地刷新 xaml 内容页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51865568/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com