.NET 9 MAUI CollectionView无法显示数据求助
问题:MAUI CollectionView无法显示查询结果(仅能显示记录数)
我使用Microsoft Visual Studio Community 2022(64位)版本17.12.3,搭配CommunityToolkit.Mvvm开发MAUI应用。现有文件包括CasesPage.xaml、CasesPage.xaml.cs、CasesPageModel(ViewModel)以及Model文件ReportedCasesView.cs。目前的问题是:CollectionView能正确显示检索到的记录数,但具体数据无法展示。以下是相关代码文件:
CasesPage.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" x:Class="Bmcl.GhanaLawReport.Pages.CasesPage" xmlns:local="clr-namespace:Bmcl.GhanaLawReport.Services" xmlns:pagemodel="clr-namespace:Bmcl.GhanaLawReport.PageModels" x:DataType="pagemodel:CasesPageModel" xmlns:sfradiobutton="clr-namespace:Syncfusion.Maui.Buttons;assembly=Syncfusion.Maui.Buttons" xmlns:inputLayout="clr-namespace:Syncfusion.Maui.Core;assembly=Syncfusion.Maui.Core" xmlns:editors="clr-namespace:Syncfusion.Maui.Inputs;assembly=Syncfusion.Maui.Inputs" xmlns:syncfusion="clr-namespace:Syncfusion.Maui.ListView;assembly=Syncfusion.Maui.ListView" Title="Reported Cases"> <ContentPage.BindingContext> <pagemodel:CasesPageModel /> </ContentPage.BindingContext> <ScrollView> <VerticalStackLayout> <Label Margin="10,0,10,0" Text="Ghana Law Reports" VerticalOptions="Center" HorizontalOptions="Center" FontSize="Title" /> <Image Source="ghanacoatofarms.png" HeightRequest="50" Aspect="AspectFit" /> <StackLayout Margin="5"> <sfradiobutton:SfRadioGroup x:Name="CasesGroup"> <sfradiobutton:SfRadioButton x:Name="ReportYear" Text="Case By Report Year" CheckedColor="Red" UncheckedColor="Black" StateChanged="ReportYear_StateChanged"/> <!--Setting ItemsSource--> <editors:SfComboBox x:Name="LawReportComboBox" WidthRequest="250" HeightRequest = "50" IsEnabled="False" DisplayMemberPath="ReportName" TextMemberPath="ReportName" ItemsSource="{Binding LawReportList}" SelectionChanged="LawReportComboBox_SelectionChanged"/> <sfradiobutton:SfRadioButton x:Name="AnyTextCaseTitle" Text="Case Title By Any Text" CheckedColor="Red" UncheckedColor="Black" StateChanged="AnyTextCaseTitle_StateChanged"/> <Entry x:Name="CaseTitleEntry" IsEnabled="False" TextChanged="CaseTitleEntry_TextChanged" Margin="30,0,10,0"/> </sfradiobutton:SfRadioGroup> </StackLayout> <StackLayout Margin="10"> <Button x:Name="Search" Text="Search" BackgroundColor="Red" TextColor="White" Command="{Binding SearchCommand}"/> </StackLayout> <VerticalStackLayout Margin="0,10,0,10"> <Label Text="{Binding RecordsReturned}" TextColor="Red" FontSize="13" FontAttributes="Bold" VerticalTextAlignment="Center" HorizontalTextAlignment="Center"/> </VerticalStackLayout> <!--ListView Area--> <CollectionView x:Name="CasesCollectionView" SelectionMode="Single" EmptyView="No Data" ItemsLayout="VerticalGrid" ItemsSource="{Binding CaseTitlesList}"> <CollectionView.ItemTemplate> <DataTemplate> <VerticalStackLayout Padding="5" Margin="10" VerticalOptions="Center"> <Label Text="{Binding CaseName}" FontSize="Medium"/> <Label Text="{Binding CourtName}" FontSize="Small"/> <Label Text="{Binding ReportName}" FontSize="Small"/> </VerticalStackLayout> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView> </VerticalStackLayout> </ScrollView> </ContentPage>
CasesPage.xaml.cs
using Bmcl.GhanaLawReport.Models; using Bmcl.GhanaLawReport.PageModels; using Bmcl.GhanaLawReport.Services; namespace Bmcl.GhanaLawReport.Pages; public partial class CasesPage : ContentPage { public CasesPage() { InitializeComponent(); } private void ReportYear_StateChanged(object sender, Syncfusion.Maui.Buttons.StateChangedEventArgs e) { if(e.IsChecked.HasValue && e.IsChecked.Value) { AppProperties.ReportedCasesSearchOption = 1; LawReportComboBox.IsEnabled = true; } else { LawReportComboBox.IsEnabled = false; } } private void AnyTextCaseTitle_StateChanged(object sender, Syncfusion.Maui.Buttons.StateChangedEventArgs e) { if(e.IsChecked.HasValue && e.IsChecked.Value) { AppProperties.ReportedCasesSearchOption = 2; CaseTitleEntry.IsEnabled = true; } else { CaseTitleEntry.IsEnabled = false; } } private void CaseTitleEntry_TextChanged(object sender, TextChangedEventArgs e) { AppProperties.ReportedCasesAnyTextParameter = CaseTitleEntry.Text; } private void LawReportComboBox_SelectionChanged(object sender, Syncfusion.Maui.Inputs.SelectionChangedEventArgs e) { AppProperties.LawReportComboParameter = LawReportComboBox.Text; } }
CasesPageModel.cs(ViewModel)
using Bmcl.GhanaLawReport.Models; using Bmcl.GhanaLawReport.Services; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using System.Collections.ObjectModel; namespace Bmcl.GhanaLawReport.PageModels { public partial class CasesPageModel : ObservableObject { private Int32 totalRecords = 0; [ObservableProperty] string recordsReturned = ""; [ObservableProperty] ObservableCollection<ReportedCasesView> caseTitlesList = []; [ObservableProperty] ObservableCollection<LawReportIndexView> lawReportList = []; [ObservableProperty] int indexId = 0; [ObservableProperty] int caseId = 0; [ObservableProperty] int courtId = 0; [ObservableProperty] int reportId = 0; [ObservableProperty] string? caseName; [ObservableProperty] string? courtName; [ObservableProperty] string? reportName; [ObservableProperty] string? judges; public CasesPageModel() { GetLawReports(); } private void GetLawReports() { var lawReports = Data.LawReport.ReadAllLawReports.Read(); if (lawReports != null) LawReportList = new ObservableCollection<LawReportIndexView>(lawReports); } [RelayCommand] public async Task Search() { await GetSerchOptions(); } private async Task GetSerchOptions() { switch(AppProperties.ReportedCasesSearchOption) { case 1: if(AppProperties.LawReportComboParameter == string.Empty || AppProperties.LawReportComboParameter == null) { //--Message here if(Application.Current?.Windows.Count > 0) { var page = Application.Current.Windows[0].Page; if(page != null) { await page.DisplayAlert("Reported Case Error", "Please select a Law Report ", "OK"); } } return; } var caseTitles = await Data.ReportedCase.ReadCaseTitleByReport.ReadAsync(AppProperties.LawReportComboParameter); if (caseTitles != null) { CaseTitlesList = new ObservableCollection<ReportedCasesView>(caseTitles); totalRecords = caseTitles.Count; RecordsReturned = $"Showing {totalRecords} Returned Records"; } break; case 2: if(AppProperties.ReportedCasesAnyTextParameter == string.Empty || AppProperties.ReportedCasesAnyTextParameter == null) { //--Message here if(Application.Current?.Windows.Count > 0) { var page = Application.Current.Windows[0].Page; if(page != null) { await page.DisplayAlert("Reported Case Error", "Please supply a Case Title ", "OK"); } } return; } var cases = await Data.ReportedCase.ReadCaseTitleByAnyText.ReadAsync(AppProperties.ReportedCasesAnyTextParameter); if (cases != null) { CaseTitlesList = new ObservableCollection<ReportedCasesView>(cases); totalRecords = cases.Count; RecordsReturned = $"Showing {totalRecords} Returned Records"; } break; } } } }
ReportedCasesView.cs(Model)
namespace Bmcl.GhanaLawReport.Models { public class ReportedCasesView { public int IndexId { get; set; } public int CaseId { get; set; } public int CourtId { get; set; } public int ReportId { get; set; } public string? CaseName { get; set; } public string? CourtName { get; set; } public string? ReportName { get; set; } public string? Judges { get; set; } } }
解决方案
1. 为DataTemplate指定编译时绑定类型
MAUI的编译时绑定需要明确DataTemplate的模型类型,否则可能出现绑定失败但无明显报错的情况。修改CasesPage.xaml:
- 首先在ContentPage的命名空间声明中添加模型命名空间:
xmlns:models="clr-namespace:Bmcl.GhanaLawReport.Models" - 然后为
DataTemplate指定x:DataType:<CollectionView.ItemTemplate> <DataTemplate x:DataType="models:ReportedCasesView"> <VerticalStackLayout Padding="5" Margin="10" VerticalOptions="Center"> <Label Text="{Binding CaseName}" FontSize="Medium"/> <Label Text="{Binding CourtName}" FontSize="Small"/> <Label Text="{Binding ReportName}" FontSize="Small"/> </VerticalStackLayout> </DataTemplate> </CollectionView.ItemTemplate>
2. 验证数据有效性
在ViewModel的查询逻辑中添加调试输出,确认返回的ReportedCasesView实例属性是否有值:
if (cases != null) { CaseTitlesList = new ObservableCollection<ReportedCasesView>(cases); totalRecords = cases.Count; RecordsReturned = $"Showing {totalRecords} Returned Records"; // 调试输出验证数据 foreach(var item in cases) { System.Diagnostics.Debug.WriteLine($"CaseName: {item.CaseName}, CourtName: {item.CourtName}"); } }
3. 检查绑定拼写
确认XAML中绑定的属性名称(如CaseName、CourtName)与ReportedCasesView类的属性名称完全一致,大小写必须匹配。
4. 查看输出窗口的绑定警告
运行应用时查看Visual Studio的输出窗口,若存在类似Binding: Property 'XXX' not found的警告,可直接定位绑定错误点。
内容的提问来源于stack exchange,提问作者Bainn
相关产品推荐
相关产品推荐

