我用C#编写了一个Xamarin应用程序,它可以注册条形码扫描。拣选器收集物品,扫描它们,然后为客户把它们放进盒子里。
在应用程序中,选择器可以查看每个框中的所有文章。他所要做的就是切换页面上的开关。动态地为每个框创建一个包含文章的网格,并添加到UI中。这种加载需要大量时间,经常超时或不完整。我试图通过使用async/await使UI更具响应性,我想看到的是,这些框可以更快地加载,并在UI上逐个显示,而不是在最后显示。有人能帮我吗?
XAML:
<ContentPage Title="Box" x:Name="cp2">
<StackLayout Orientation="Vertical" HeightRequest="20">
<StackLayout Orientation="Horizontal" Margin="0" Spacing="0">
<Label VerticalOptions="Center" Text="Boxnr:"/>
<Entry x:Name="txtBoxNr" VerticalOptions="Center" HorizontalOptions="StartAndExpand" WidthRequest="200"
Text="{Binding CurrBoxNr}" FontSize="Small" IsEnabled="{Binding BoxNrEnabled}" Completed="txtBoxNr_Completed"/>
</StackLayout>
<StackLayout x:Name="txtOverviewTitle" Orientation="Vertical" Margin="0,10,0,0" Spacing="0" IsVisible="False">
<StackLayout Orientation="Horizontal" Margin="0,0,0,0" Spacing="0" BackgroundColor="Maroon">
<Label VerticalOptions="Start" HorizontalOptions="FillAndExpand"
Text="Scan overview" FontSize="22" TextColor="White" HorizontalTextAlignment="Center"/>
<Switch x:Name="swOverview" VerticalOptions="Center" Toggled="swOverview_Toggled" IsToggled="False"/>
</StackLayout>
<StackLayout x:Name="Loader" Orientation="Vertical" IsVisible="false">
<Label x:Name="message1" Text="Loading overview. Please wait..." TextColor="Maroon" IsVisible="false"/>
<Label x:Name="message2" Text="Closing overview. Please wait..." TextColor="Maroon" IsVisible="false"/>
<ActivityIndicator x:Name="ailoader" Color="Maroon" IsRunning="false"/>
</StackLayout>
<Label x:Name="txtUsedBoxes" Margin="10,10,10,5" VerticalOptions="Start" Text="" IsVisible="false"/>
<BoxView x:Name="bvLine" HeightRequest="1" HorizontalOptions="FillAndExpand" VerticalOptions="End" BackgroundColor="Maroon" IsVisible="false"/>
</StackLayout>
<ScrollView x:Name="scrloverview">
<StackLayout x:Name="Overview" Orientation="Vertical" IsVisible="false"/>
</ScrollView>
</StackLayout>
</ContentPage>
XAML.cs:
private void swOverview_Toggled(object sender, ToggledEventArgs e)
{
if (e.Value == true)
GetOverview();
else
RemoveOverview();
}
private async void GetOverview()
{
message1.IsVisible = true;
ailoader.IsRunning = true;
Loader.IsVisible = true;
#region 1. Clear all children under the StackLayout
Overview.Children.Clear();
#endregion
#region 2. Display the overview title and the used boxes (without box 0)
IEnumerable<decimal> boxes = viewModel.Scanlist
.Where(c => c.Box > 0)
.OrderBy(c => c.Box)
.Select(c => c.Box).Distinct();
string strboxes = "Used Boxes: ";
for (int i = 0; i < boxes.Count(); i++)
{
if (boxes.ElementAt(i) > 0)
{
strboxes += (boxes.ElementAt(i)).ToString("N0");
if (i < boxes.Count() - 1)
strboxes += ", ";
}
}
txtUsedBoxes.Text = strboxes;
#endregion
#region 3. Insert the overview of the scanned articles per box
foreach (decimal box in boxes)
{
await Task.Run(async () =>
{
try
{
Device.BeginInvokeOnMainThread(() => AddGridBox(box));
}
catch (Exception exp)
{
await DisplayAlert("Error", exp.Message, "OK");
}
});
}
#endregion
#region 4. Insert the overview of the unscanned articles in box 0
await Task.Run(async () =>
{
try
{
Device.BeginInvokeOnMainThread(() => AddGrid0());
}
catch (Exception exp)
{
await DisplayAlert("Error", exp.Message, "OK");
}
});
Loader.IsVisible = false;
message1.IsVisible = false;
ailoader.IsRunning = false;
#endregion
txtUsedBoxes.IsVisible = true;
bvLine.IsVisible = true;
Overview.IsVisible = true;
}
private async void RemoveOverview()
{
Loader.IsVisible = true;
message2.IsVisible = true;
ailoader.IsRunning = true;
Overview.IsVisible = false;
txtUsedBoxes.Text = "";
txtUsedBoxes.IsVisible = false;
bvLine.IsVisible = false;
await Task.Run(async () =>
{
try
{
Device.BeginInvokeOnMainThread(() => {
Overview.Children.Clear();
});
}
catch (Exception exp)
{
await DisplayAlert("Error", exp.Message, "OK");
}
});
message2.IsVisible = false;
ailoader.IsRunning = false;
Loader.IsVisible = false;
}
1条答案
按热度按时间4urapxun1#
我怀疑Xamarin不会立即开始显示更新,因为它试图优化同时进行多个UI更改的情况;为了保存时间,它更喜欢用所有这些改变一起进行显示更新。
可以强制布局循环:
警告:如果您一次显示一个框,则所用的总时间可能会增加。请考虑大约每隔三个框强制显示一次。