.NET MAUI继承ContentView控件时绑定失效问题排查与解决
.NET MAUI 继承ContentView绑定问题排查与解决
需求背景
实现一个名称/值对显示控件,通过继承拆分逻辑:基控件负责展示名称,子控件负责展示值。基控件是包含Label的Grid,暴露ControlName可绑定属性,同时提供一个ContentView供子控件填充值内容;子控件继承基控件,暴露ControlTextValue可绑定属性,在基控件的ContentView中用Label展示该值。
基控件实现
XAML代码
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Name="thisControlBase" x:Class="MauiPlayground.Controls.NameValueControlBase"> <Grid BindingContext="{x:Reference thisControlBase}"> <Label Text="{Binding ControlName}" VerticalOptions="Center" HorizontalOptions="Start" /> <ContentView x:Name="ControlValueContentView" /> </Grid> </ContentView>
后台代码
public partial class NameValueControlBase : ContentView { public static readonly BindableProperty ControlNameProperty = BindableProperty.Create( propertyName: nameof(ControlName), returnType: typeof(string), declaringType: typeof(NameValueControlBase), defaultValue: string.Empty, defaultBindingMode: BindingMode.OneWay); public string ControlName { get => (string)GetValue(ControlNameProperty); set => SetValue(ControlNameProperty, value); } public View ControlValueContent { get => this.ControlValueContentView.Content; set => this.ControlValueContentView.Content = value; } public NameValueControlBase() { InitializeComponent(); } }
子控件实现
初始有问题的XAML代码
<ctrl:NameValueControlBase xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:ctrl="clr-namespace:MauiPlayground.Controls" x:Name="thisNameValueControlBase" x:Class="MauiPlayground.Controls.TextNameValueControl"> <ctrl:NameValueControlBase> <ctrl:NameValueControlBase.ControlValueContent> <HorizontalStackLayout VerticalOptions="Center" HorizontalOptions="End" BindingContext="{x:Reference thisNameValueControlBase}"> <Label BindingContext="{x:Reference thisNameValueControlBase}" Text="{Binding ControlTextValue}" /> </HorizontalStackLayout> </ctrl:NameValueControlBase.ControlValueContent> </ctrl:NameValueControlBase> </ctrl:NameValueControlBase>
后台代码
public partial class TextNameValueControl : NameValueControlBase { public static readonly BindableProperty ControlTextValueProperty = BindableProperty.Create( propertyName: nameof(ControlTextValue), returnType: typeof(string), declaringType: typeof(TextNameValueControl), defaultValue: string.Empty, defaultBindingMode: BindingMode.OneWay); public string ControlTextValue { get => (string)GetValue(ControlTextValueProperty); set => SetValue(ControlTextValueProperty, value); } public TextNameValueControl() { InitializeComponent(); } }
主页面使用代码
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:controls="clr-namespace:MauiPlayground.Controls" x:Class="MauiPlayground.MainPage"> <VerticalStackLayout> <controls:TextNameValueControl ControlName="Employee Name" ControlTextValue="John Doe" /> </VerticalStackLayout> </ContentPage>
问题现象
运行后子控件的ControlTextValue("John Doe")能正常显示,但基控件的ControlName("Employee Name")完全不显示。尝试修改控件x:Name为"this"、移除绑定改用事件处理器设置Label文本等操作都无效,而相同的继承逻辑在Xamarin中可以正常工作。
问题原因与解决
问题出在子控件的XAML定义中:多嵌套了一层<ctrl:NameValueControlBase>标签,导致原本的基控件实例被覆盖,外部设置的ControlName属性传递不到真正负责显示的基控件上。
修正后的子控件XAML代码
移除冗余的嵌套层级即可解决问题:
<ctrl:NameValueControlBase xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:ctrl="clr-namespace:MauiPlayground.Controls" x:Name="thisNameValueControlBase" x:Class="MauiPlayground.Controls.TextNameValueControl"> <ctrl:NameValueControlBase.ControlValueContent> <HorizontalStackLayout VerticalOptions="Center" HorizontalOptions="End" BindingContext="{x:Reference thisNameValueControlBase}"> <Label BindingContext="{x:Reference thisNameValueControlBase}" Text="{Binding ControlTextValue}" /> </HorizontalStackLayout> </ctrl:NameValueControlBase.ControlValueContent> </ctrl:NameValueControlBase>
内容的提问来源于stack exchange,提问作者adiaz
相关产品推荐
相关产品推荐

