You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 07:54:49