.NET MAUI调试正常发布模式绑定数据不显示问题求助
.NET MAUI Android 14发布模式下自定义视图与CollectionView数据空白问题
调试模式下数据显示正常,但发布模式中ClassNameView自定义视图和CollectionView内的数据无法显示,仅能看到空白。已确认数据已正确加载(CollectionView行数符合预期),将自定义视图的XML直接嵌入页面时数据显示正常。
ObservationHistoryPage.xaml
<ContentPage x:Class="SchoolApp.Views.ObservationHistoryPage" xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:custom="clr-namespace:SchoolApp.Custom" xmlns:resx="clr-namespace:SchoolApp.Resources.Strings" xmlns:skia="clr-namespace:SkiaSharp.Extended.UI.Controls;assembly=SkiaSharp.Extended.UI" xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit" xmlns:vm="clr-namespace:SchoolApp.ViewModels" Title="{x:Static resx:AppResources.ObservationsHistory}" x:DataType="vm:ObservationHistoryPageViewModel"> <ContentPage.Behaviors> <toolkit:EventToCommandBehavior Command="{Binding NavigatedToCommand}" EventName="NavigatedTo" /> </ContentPage.Behaviors> <Grid> <custom:LoadingAndErrorView Display="{Binding Display}" ErrorDescription="{Binding ErrorMessage}" ErrorTitle="{Binding ErrorTitle}" RetryCommand="{Binding LoadInfoCommand}" /> <ScrollView> <VerticalStackLayout Padding="10" IsVisible="{Binding DisplayData}" Spacing="10"> <!-- Class Name --> <custom:ClassNameView ClassName="{Binding ClassName}" /> <Label HorizontalOptions="Center" Style="{StaticResource LargeLabelBold}" Text="{x:Static resx:AppResources.ObservationHistory}" /> <!-- Count --> <HorizontalStackLayout Padding="0,0,5,0" HorizontalOptions="End"> <Label Style="{StaticResource MediumLabelItalic}" Text="Total:" /> <Label Style="{StaticResource MediumLabelItalic}" Text="{Binding ObservationCount}" /> </HorizontalStackLayout> <!-- Dates --> <CollectionView ItemsSource="{Binding Dates}" SelectionMode="None"> <CollectionView.ItemTemplate> <DataTemplate> <Grid Padding="10" ColumnDefinitions="80,*"> <Image HorizontalOptions="Center" Source="calendar" WidthRequest="68" /> <Label Grid.Column="1" HorizontalOptions="Center" Style="{StaticResource LargeLabelBold}" Text="{Binding ., StringFormat='{0:dd / MMMM / yyyy }'}" VerticalOptions="Center" /> </Grid> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView> <!-- close button --> <Button Command="{Binding CloseCommand}" IsVisible="{Binding IsNotBusy}" Style="{x:StaticResource ButtonOutline}" Text="{x:Static resx:AppResources.Close}" /> </VerticalStackLayout> </ScrollView> </Grid> </ContentPage>
ObservationHistoryPageViewModel.cs
using SchoolApp.Models.Observations; namespace SchoolApp.ViewModels { [QueryProperty(nameof(Observation), nameof(Observation))] [QueryProperty(nameof(ClassName), nameof(ClassName))] public partial class ObservationHistoryPageViewModel : BaseViewModel { private readonly ObservationsService _observationsService; [ObservableProperty] ObservationStudentComplete _observation; [ObservableProperty] string _className; [ObservableProperty] [NotifyPropertyChangedFor(nameof(ObservationCount))] List<DateTime> _dates=new List<DateTime>(); public int ObservationCount => Dates.Count; public ObservationHistoryPageViewModel(ObservationsService observationsService) { _observationsService = observationsService; } [RelayCommand] public async Task NavigatedTo() { await LoadInfo(); } [RelayCommand] public async Task LoadInfo() { SetPageInLoadingState(); var result = await _observationsService.GetObservationHistory(Selected.Student.IdAlumno, Selected.Organization.IsParent, Observation); SetDisplayAndErrorsFromResult(result); Dates = result.Item ?? new List<DateTime>(); SetPageInFinishLoadingState(); } [RelayCommand] public async Task Close() { await Shell.Current.GoToAsync(".."); } } }
ClassNameView.xaml
<Grid x:Class="SchoolApp.Custom.ClassNameView" xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:custom="clr-namespace:SchoolApp.Custom" x:DataType="custom:ClassNameView" ColumnDefinitions="80,*"> <Image Source="books" WidthRequest="60" /> <Label Grid.Column="1" Style="{x:StaticResource LargeLabelBold}" Text="{Binding ClassName}" VerticalOptions="Center" /> </Grid>
ClassNameView.xaml.cs
namespace SchoolApp.Custom; public partial class ClassNameView : Grid { public static readonly BindableProperty ClassNameProperty = BindableProperty.Create(nameof(ClassName) , typeof(string) , typeof(ClassNameView) , default(string) , propertyChanged: (bindable, value, newValue) => ((ClassNameView)bindable).ClassName = (string)newValue); public string ClassName { get => (string)GetValue(ClassNameProperty); set => SetValue(ClassNameProperty, value); } public ClassNameView() { InitializeComponent(); } }
问题原因及解决方法
1. 自定义视图ClassNameView绑定错误
发布模式下XAML编译优化会严格解析绑定规则,你的自定义视图存在两个问题:
- BindableProperty的
propertyChanged回调手动给CLR属性赋值,会触发无限循环并破坏绑定同步机制。 - XAML中绑定
ClassName未明确指定源为视图自身,发布模式下无法正确解析绑定上下文。
修复ClassNameView.xaml.cs:
移除propertyChanged回调,BindableProperty会自动同步CLR属性:
public static readonly BindableProperty ClassNameProperty = BindableProperty.Create( nameof(ClassName), typeof(string), typeof(ClassNameView), default(string)); public string ClassName { get => (string)GetValue(ClassNameProperty); set => SetValue(ClassNameProperty, value); }
修复ClassNameView.xaml:
明确绑定源为自身:
<Label Grid.Column="1" Style="{x:StaticResource LargeLabelBold}" Text="{Binding ClassName, Source={RelativeSource Self}}" VerticalOptions="Center" />
2. CollectionView的DataTemplate未指定类型
发布模式下未指定DataTemplate的x:DataType会导致绑定失效,需明确绑定的DateTime类型:
修复ObservationHistoryPage.xaml中的CollectionView:
<CollectionView ItemsSource="{Binding Dates}" SelectionMode="None"> <CollectionView.ItemTemplate> <DataTemplate x:DataType="x:DateTime"> <Grid Padding="10" ColumnDefinitions="80,*"> <Image HorizontalOptions="Center" Source="calendar" WidthRequest="68" /> <Label Grid.Column="1" HorizontalOptions="Center" Style="{StaticResource LargeLabelBold}" Text="{Binding ., StringFormat='{0:dd / MMMM / yyyy }'}" VerticalOptions="Center" /> </Grid> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView>
3. 发布模式代码收缩优化问题
默认发布配置的代码收缩可能移除绑定所需元数据,需修改项目文件(.csproj):
<PropertyGroup Condition="'$(Configuration)' == 'Release'"> <AndroidLinkMode>SdkOnly</AndroidLinkMode> <MauiLinkMode>SdkOnly</MauiLinkMode> <EnableTrimAnalyzer>false</EnableTrimAnalyzer> </PropertyGroup>
内容的提问来源于stack exchange,提问作者Salvador Cruz
相关产品推荐
相关产品推荐

