我是 .NET Maui 的新手,我正在创建我的第一个应用程序,该应用程序首先检查 dll 文件的接口实现,然后用户输入一个数字,程序应该输出最多到它的所有素数。问题出现在可视化中,当处理大量数据时,我的应用程序本身会挂起,所以我决定将其设为异步。这没有帮助,因为当可视化尝试列出这些数字时,它本身会挂起。然后我决定添加逐渐滚动,但它不起作用。在调试中这个事件不起作用。 这是 MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:PrimeNumApp"
x:Class="PrimeNumApp.MainPage">
<VerticalStackLayout
Padding="30,0"
Spacing="25">
<Label
Text="Cписок простых чисел"
Style="{StaticResource Headline}"
SemanticProperties.HeadingLevel="Level1" />
<Image
Source="kitten.gif"
HeightRequest="200"
HorizontalOptions="Center"
IsAnimationPlaying="True" />
<Entry
x:Name="NumberEntry"
Placeholder="Введите число" />
<StackLayout
Orientation="Horizontal"
Spacing="5"
>
<Button
x:Name="LoadBtn"
Text="Загрузить сборку"
Clicked="OnLoadClicked"
HorizontalOptions="FillAndExpand"
BackgroundColor="Gray" />
<Button
x:Name="StartBtn"
Text="Посчитать"
Clicked="OnStartClicked"
IsEnabled="False"
HorizontalOptions="FillAndExpand"
BackgroundColor="DarkRed" />
</StackLayout>
<CollectionView x:Name="PrimeNumCollection"
RemainingItemsThreshold="5"
RemainingItemsThresholdReached="OnCollectionViewRemainingItemsThresholdReached">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Vertical" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding}"
TextColor="White"/>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</VerticalStackLayout>
</ContentPage>
这是 MainPage.xaml.cs
using Contract;
using Microsoft.Maui.Controls;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Reflection;
using System.Text;
namespace PrimeNumApp
{
public partial class MainPage : ContentPage, INotifyPropertyChanged
{
private bool _isImplemented;
private Assembly _assembly;
private string _realizationPath;
private IPrimeGenerator _primeNumberGenerator;
private const int PageSize = 5;
private int _currentPage = 0;
public ObservableCollection<int> DisplayablePrimeNums { get; set; }
private List<int> _allPrimeNumbers = new List<int>();
public MainPage()
{
InitializeComponent();
DisplayablePrimeNums = new ObservableCollection<int>();
PrimeNumCollection.ItemsSource = DisplayablePrimeNums;
PrimeNumCollection.RemainingItemsThresholdReached += OnCollectionViewRemainingItemsThresholdReached;
}
public async void OnStartClicked(object sender, EventArgs e)
{
if (int.TryParse(NumberEntry.Text, out int number))
{
try
{
_allPrimeNumbers = await Task.Run(() => _primeNumberGenerator!.GetPrimeNumbers(number));
DisplayablePrimeNums.Clear();
LoadNextPage();
}
catch (Exception ex)
{
await DisplayAlert("Ошибка", ex.Message, "OK");
}
}
else
{
await DisplayAlert("Ошибка", "Вы ввели не натуральное число", "OK");
}
}
private void LoadNextPage()
{
foreach (int number in _allPrimeNumbers.GetRange(_currentPage, PageSize))
{
DisplayablePrimeNums.Add(number);
}
_currentPage += PageSize;
}
public void OnCollectionViewRemainingItemsThresholdReached(object sender, EventArgs e)
{
LoadNextPage();
}
public async void OnLoadClicked(object sender, EventArgs e)
{
await PickDll();
}
private async Task PickDll()
{
var customFileType = new FilePickerFileType(
new Dictionary<DevicePlatform, IEnumerable<string>>
{
{ DevicePlatform.WinUI, new[] { ".dll" } },
});
try
{
var result = await FilePicker.PickAsync(new PickOptions()
{
FileTypes = customFileType,
PickerTitle = "Выберите файл формата .dll"
});
if (result != null)
{
_realizationPath = result.FullPath;
await LoadDll();
}
}
catch (Exception ex)
{
await DisplayAlert("Ошибка", "Ошибка при загрузке сборки: " + ex.Message, "OK");
}
}
private async Task LoadDll()
{
_assembly = Assembly.LoadFrom(_realizationPath);
await CheckContractRealization();
}
private async Task CheckContractRealization()
{
_isImplemented = _assembly.GetTypes().Any(type => type.GetInterfaces().Contains(typeof(IPrimeGenerator)));
if (_isImplemented)
{
LoadBtn.BackgroundColor = Colors.Green;
StartBtn.IsEnabled = true;
StartBtn.BackgroundColor = Colors.Gray;
var primeGeneratorType = _assembly.GetTypes()
.Where(type => typeof(IPrimeGenerator).IsAssignableFrom(type) && type.IsClass)
.Select(type => type)
.First();
_primeNumberGenerator = (IPrimeGenerator)Activator.CreateInstance(primeGeneratorType)!;
}
else
{
await DisplayAlert("Ошибка", "Реализация не соответсвует контракту", "OK");
}
}
}
}
我尝试更改和删除滚动条本身,在 CollectionView 中显示 DataTemplate,但它不起作用
提供的源代码存在多个问题:
OnCollectionViewRemainingItemsThresholdReached
检测您是否即将到达列表末尾的功能,然后获取更多数据。几乎没有什么问题需要你解决。您已经在 xaml 中声明了该事件,但也在构造函数中进行了声明。所以只做一次。然后,例如,如果您获得前 20 个素数,那么当您到达最后 5 个素数时,将调用方法 OnCollectionViewRemainingItemsThresholdReached
,您可以在其中加载 20 个以上素数。