I have a Grid inside ListBox in my UWP C# application.
There is no problem with small grid.
However, when a Grid has over 50 cells with multiple rows and columns, removing the grid from its parent is very slow. It takes over 1 minute or about 2 minutes.
I tried to hide it by changing its Visibility to Collapsed or Opacity to 0 or building a release executable but still too slow as the same.
ToList().Clear() works fast in some case, but not enough.
ListBox rootBox = new ListBox();
rootBox.Items.Add(grid); // adding a complex Grid with over 50 cells with inner UI elements like TextBlock, TextBox and so on.
rootBox.Items.Remove(grid); <--- takes about 2 minutes with CPU utilization under 15% in my modern PC
There's no APIs to suspend and resume layout update in UWP.
Dynamically manipulating a UWP Grid element seems unpractically slow to me.
I tried to find a way to optimize performance for Grid UI, but failed.
Profiling showed me that layout task takes about 50% of CPU of the process but not intensive even in 1 core. It means the slowness is not from CPU-intensive calculation.
Oh, I tried to simplify the problem and found the case.
A grid inside multiple nested ListBoxes!
Nesting more ListBox makes the program slower.
You could reproduce the case by clicking the bottom 'Clear' button of the program below.
Reproduction code:
------------------ MainPage.xaml -----------------
<Page
x:Class="GridSlow.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:GridSlow"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Loaded="OnLoaded_Page"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid Name="rootGrid">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ScrollViewer HorizontalScrollBarVisibility="Visible" Grid.Row="0">
<ListBox Name="innerList">
</ListBox>
</ScrollViewer>
<Button Content="Clear" Click="Button_Click" Grid.Row="1"/>
</Grid>
</Page>
------------------------ MainPage.xaml.cs -----------------------
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
namespace GridSlow
{
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private void OnLoaded_Page(object sender, RoutedEventArgs args)
{
Grid grid = new Grid();
for (int row = 0; row < 50; ++row)
{
RowDefinition rowDef = new RowDefinition();
rowDef.Height = new GridLength(0, GridUnitType.Auto);
rowDef.MinHeight = 10;
grid.RowDefinitions.Add(rowDef);
for (int col = 0; col < 2; ++col)
{
ColumnDefinition colDef = new ColumnDefinition();
colDef.Width = new GridLength(0, GridUnitType.Auto);
colDef.MinWidth = 10;
grid.ColumnDefinitions.Add(colDef);
Border border = new Border() { BorderBrush = new SolidColorBrush(Colors.DarkGray), BorderThickness = new Thickness(1) };
TextBox textBox = new TextBox();
textBox.Text = "aaa";
border.Child = textBox;
grid.Children.Add(border);
Grid.SetRow(border, row);
Grid.SetColumn(border, col);
}
}
ListBox list2 = new ListBox();
ListBox list3 = new ListBox();
ListBox list4 = new ListBox();
ListBox list5 = new ListBox();
ListBox list6 = new ListBox();
TextBox box2 = new TextBox();
box2.Margin = new Thickness(1);
list2.Items.Add(box2);
list2.Items.Add(list3);
list3.Items.Add(new TextBox());
list3.Items.Add(list4);
list4.Items.Add(list5);
list5.Items.Add(list6);
list6.Items.Add(grid);
innerList.Items.Add(list2);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
innerList.Items.Clear();
}
}
}
question from:
https://stackoverflow.com/questions/65859296/removing-a-uwp-grid-is-too-slow 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…