我有有效的代码,但我注意到创建页面元素相当慢。
这是我到目前为止所拥有的。请注意,我不会一次添加所有内容,因为我发现创建页面时速度更慢。
public void CreateSwitchSection(bool? selected)
{
Application.Current.Resources.TryGetValue("FrameBorder", out object frameBorder);
var st = new StackLayout { Orientation = StackOrientation.Vertical, Spacing = 0 };
st.Children.Add(AddSwitchRows(selected, App.cardSetWithWordCount.Take(20)));
st.Children.Add(AddSwitchRows(selected, App.cardSetWithWordCount.Skip(20).Take(20)));
st.Children.Add(AddSwitchRows(selected, App.cardSetWithWordCount.Skip(40).Take(20)));
st.Children.Add(AddSwitchRows(selected, App.cardSetWithWordCount.Skip(60).Take(20)));
st.Children.Add(AddSwitchRows(selected, App.cardSetWithWordCount.Skip(80).Take(20)));
var fr = new Frame { Style = (Style)frameBorder };
var fs = new FrameStack { };
var ht = new HeaderTemplate()
{
Text = "CHOOSE CARD SETS FOR THE DECK"
};
fs.Children.Add(ht);
fs.Children.Add(st);
fs.Children.Add(new LineTemplate());
fr.Content = fs;
details.Children.Clear();
details.Children.Add(fr);
}
private StackLayout AddSwitchRows(bool? selected, IEnumerable<CardSetWithWordCount> data)
{
var stack = new StackLayout
{
Orientation = StackOrientation.Vertical,
Spacing = 0
};
foreach (var x in data)
{
var cell = new BadgeGridTemplate
{
BindingContext = x,
Text = x.Name,
State = selected == true ? "E" : "D",
Message = x.TotalWordCount.ToString(),
TapCommand = (Command)vm.SelectCardSetCmd,
RowId = x.Id,
Separator = true
};
stack.Children.Add(cell);
}
return stack;
}
这里是我编码的 BadgeGridTemplate 供引用:
<?xml version="1.0" encoding="UTF-8"?>
<t:BaseGridTemplate xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:t="clr-namespace:Japanese.Templates"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:Japanese;assembly=Japanese"
xmlns:b="clr-namespace:Behaviors;assembly=Behaviors"
xmlns:converters="clr-namespace:Japanese.Converters;assembly=Japanese"
x:Class="Japanese.Templates.BadgeGridTemplate"
x:Name="this"
HeightRequest="{DynamicResource GridHeight}" Margin="0"
Orientation="Vertical" Spacing="0">
<BoxView HeightRequest="1" HorizontalOptions="FillAndExpand" IsVisible="{Binding Separator, Source={x:Reference this}}" BackgroundColor="{DynamicResource LineColor}" Margin="0" />
<Grid Padding="20,0" VerticalOptions="CenterAndExpand">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Text="{Binding Text, Source={x:Reference this}}" TextColor="{DynamicResource LabelColor}" Style="{StaticResource LabelText}" VerticalTextAlignment="Center" WidthRequest="30" />
<t:Button Grid.Column="1" Meta="GsT" RowId="{Binding RowId, Source={x:Reference this}}" State="{Binding State, Source={x:Reference this}}" TapCommand="{Binding TapCommand, Source={x:Reference this}}" Text="{Binding Message, Source={x:Reference this}}" Theme="{Binding Theme}" WidthRequest="30" />
</Grid>
</t:BaseGridTemplate>
请您参考如下方法:
您可以尝试在子循环添加到您的函数 AddSwitchRows 和循环之后的 BatchCommit() 之前在 stacks 变量上使用 BatchBegin()。如果可行,请对 CreateSwitchSection 中的父堆栈变量 st 执行相同操作。
IE。
stacks.BatchBegin();
foreach var x 在数据中
{
…
}
stacks.BatchCommit();
这可以解决它,因为许多显示表单的语言都喜欢在每次添加/删除/更新集合/列表/子项时(昂贵)重新计算布局。批处理允许布局重新计算一次而不是每次列表更改时进行。