bounty还有7天到期。回答此问题可获得+50声望奖励。CompSciFly想吸引更多的注意力这个问题:寻找一个完整的答案,直接解决我的问题。
我已经尝试了几种不同的方法来做到这一点,但还没有完全弄清楚的组合,让这工作的预期。这是在.NET MAUI中使用.NET 6。基本上,UI不会更新/显示ListView行和值。我发现,如果在调试过程中更改.xaml(使用热重载过程),ListView的值就会神奇地出现。因此,我确信UI没有被通知ObservableCollection已经被更改。当在我的UI - MainPage.xaml中单击GetList
按钮时,将调用一个异步方法从我的API中获取数据,并使用API返回的数据填充可观察集合。下面是必要的代码:
更新:奇怪的是,将<Label Text="{Binding MyObvList.Count}" />
添加到XAML中会导致UI刷新,成功显示列表及其行/变量。然而,当这个标签被移除时,它又回到了老样子。所以,我进一步相信这是一个更新的问题。
下面是我的XAML(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:mct="clr-namespace:CommunityToolkit.Maui.Views;assembly=CommunityToolkit.Maui"
x:Class="MyApp.MainPage"
x:Name="PageRoot"
Title="My App">
<VerticalStackLayout Spacing="25" Padding="30,0" VerticalOptions="Center">
<Label Text="My App"
SemanticProperties.HeadingLevel="Level2"
FontSize="18"
HorizontalOptions="Center" />
<Button Text="Get List" Clicked="GetList"/>
<StackLayout Orientation="Horizontal">
<Label Text="Number" WidthRequest="100" />
<Label Text="Name" WidthRequest="100" />
<Label Text="Info" WidthRequest="100" />
</StackLayout>
<ListView ItemsSource="{Binding MyObvList}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal">
<Label Text="{Binding Number}" WidthRequest="100" />
<Label Text="{Binding Name}" WidthRequest="100" />
<Label Text="{Binding Info}" WidthRequest="300" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</VerticalStackLayout>
</ContentPage>
字符串
代码隐藏(MainPage.xaml.cs):
namespace MyApp;
public partial class MainPage : ContentPage, INotifyPropertyChanged
{
private ObservableCollection<MyData> _myObvList = new();
public ObservableCollection<MyData> MyObvList {
get { return _myObvList; }
set {
if(_myObvList != value) {
_myObvList = value;
OnPropertyChanged(nameof(MyObvList));
}
}
}
public MainPage()
{
InitializeComponent();
BindingContext = this;
NavigationPage.SetHasNavigationBar(this, false);
NavigationPage.SetHasBackButton(this, false);
}
async void GetList(object sender, EventArgs e)
{
try {
List<MyAPIData> apiData = await MyApi.GetDataAsync();
MainThread.BeginInvokeOnMainThread(() => {
MyObvList.Clear();
if(apiData != null && apiData.Count > 0) {
foreach(MyAPIData data in apiData) {
MyData myNewData = new();
myNewData.Name = = data.Person.FirstName + " " + (string.IsNullOrEmpty(data.Person.MiddleName) ? "" : data.Person.MiddleName + " ") + data.Person.LastName + (string.IsNullOrEmpty(data.Person.Suffix) ? "" : " " + data.Person.Suffix);
myNewData.Number = data.Number;
myNewData.Info = data.Info;
MyObvList.Add(myNewData);
}
}
}
} catch(Exception ex) {
Debug.WriteLine($"An error occurred: {ex.Message}");
}
}
}
型
下面是MyData.cs类:
public class MyData : INotifyPropertyChanged {
private string number { get; set; }
public string Number {
get { return number; }
set {
if(number != value) {
number = value;
OnPropertyChanged(nameof(Number));
}
}
}
private string name { get; set; }
public string Name {
get { return name; }
set {
if(name != value) {
name = value;
OnPropertyChanged(nameof(Name));
}
}
}
private string info { get; set; }
public string Info {
get { return info; }
set {
if(info != value) {
info = value;
OnPropertyChanged(nameof(Info));
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName) {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
型
此外,当我下一次点击按钮插入<Label Text="{Binding MyObvList.Count}" />
时,我会得到“Object reference not set to an instance of an object.”错误,因为它试图执行MyObvList.Clear();
。我已经看到了各种建议的解决方案,例如将对象设置为新的ObservableCollection<MyData>
或while(MyObvList.Any()) { MyObvList.RemoveAt(0); }
,但是,我没有任何运气,未能让列表第二次填充。我尝试切换到MVVM模型,但遇到了与上面相同的问题。所以,这里有更大的事情发生。需要解决方案。
1条答案
按热度按时间cpjpxq1n1#
我看不出代码有什么问题。
作为解决方法,在添加所有数据后,请执行以下操作:
字符串
我还建议在后台线程上获取数据:
型
在GetDataAsync运行时,按钮单击方法可能不喜欢延迟。如果上面的方法不起作用,可以这样尝试:
型