.NET MAUI迁移:设置GridLength时OnSize类报XFC0009错误
解决MAUI中OnSize类的XFC0009错误
问题场景
将Xamarin Forms应用迁移至.NET MAUI时,原用于根据设备高度动态设置GridLength的OnSize<T>类在MAUI中报错:
Error XFC0009: No property, BindableProperty, or event found for "Tiny", or mismatching type between value and property. (XFC0009)
原OnSize<T>代码:
public class OnSize<T> { /// <summary> /// 对应小屏设备(如iPhone 4S)的值 /// </summary> public T Tiny { get; set; } /// <summary> /// 对应小屏设备(如iPhone SE)的值 /// </summary> public T Small { get; set; } /// <summary> /// 对应中屏设备(如iPhone 8)的值 /// </summary> public T Medium { get; set; } /// <summary> /// 对应大屏设备(如iPhone 8 Plus或iPhone X)的值 /// </summary> public T Large { get; set; } public static implicit operator T(OnSize<T> onSize) { if(height < 500) { return onSize.Tiny; } if(height < 620) { return onSize.Small; } if(height < 700) { return onSize.Medium; } return onSize.Large; } static double height => App.Current.MainPage.Height; }
原XAML使用方式:
<Grid RowSpacing="1" VerticalOptions="FillAndExpand"> <Grid.RowDefinitions> <RowDefinition> <RowDefinition.Height> <OnSize x:TypeArguments="GridLength" Tiny="255" Small="255" Medium="275" Large="317" /> </RowDefinition.Height> </RowDefinition> </Grid>
错误原因
MAUI的XAML解析器对元素属性的要求比Xamarin Forms更严格:只有BindableProperty才能在XAML元素中直接设置属性值,而原代码中的Tiny、Small等都是普通CLR属性,不符合MAUI的解析规则。
解决方案
改用MarkupExtension实现动态值逻辑,这种方式更适配MAUI的XAML解析机制,同时保留原有的设备尺寸判断逻辑:
1. 创建泛型MarkupExtension类
using Microsoft.Maui.Controls; using Microsoft.Maui.Controls.Xaml; using System; namespace YourNamespace { [ContentProperty(nameof(Large))] public class OnSizeExtension<T> : MarkupExtension { public T Tiny { get; set; } public T Small { get; set; } public T Medium { get; set; } public T Large { get; set; } public override object ProvideValue(IServiceProvider serviceProvider) { // 确保获取到有效页面高度,避免空引用 var height = Application.Current?.MainPage?.Height ?? 0; if (height < 500) return Tiny; if (height < 620) return Small; if (height < 700) return Medium; return Large; } } }
2. 修改XAML使用方式
在XAML中通过标记扩展语法直接绑定Height属性,无需嵌套元素:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:YourNamespace" x:Class="YourNamespace.YourPage"> <Grid RowSpacing="1" VerticalOptions="FillAndExpand"> <Grid.RowDefinitions> <RowDefinition Height="{local:OnSize GridLength, Tiny=255, Small=255, Medium=275, Large=317}" /> </Grid.RowDefinitions> </Grid> </ContentPage>
说明
- MarkupExtension是MAUI中实现动态值注入的标准方式,XAML解析器会自动调用
ProvideValue方法获取最终值。 - 代码中增加了空引用判断,避免
Application.Current或MainPage为空时出现异常。 - 若需要支持更多类型(如double、Thickness等),只需在XAML中指定对应的
x:TypeArguments即可。
内容的提问来源于stack exchange,提问作者user20694704
相关产品推荐
相关产品推荐

