.NET Maui 自定义控件可绑定属性失效问题求助
.NET MAUI自定义控件可绑定属性无法传递值的解决方法
问题根源
自定义控件内部的绑定默认继承父级的BindingContext,而非控件自身。这就导致你在XAML中写{Binding SPC_ButtonName}时,程序会去父级的ViewModel里找该属性,而不是控件自己的可绑定属性;同时如果强行在构造函数设置BindingContext = this,又会破坏外部的AudioSource="{Binding PlayerSource}"绑定——因为此时外部绑定会去控件自身找PlayerSource,而非父级ViewModel。
解决方案:指定绑定源为控件自身
修改自定义控件的XAML,明确绑定的来源是控件实例(通过x:Reference引用控件的x:Name="root"),这样既能让内部绑定找到自身的可绑定属性,又不影响外部绑定继承父级BindingContext。
修改后的自定义控件XAML
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit" xmlns:customcontrols="clr-namespace:LifeTrax.Mobile.Custom_Controls" x:Class="LifeTrax.Mobile.Custom_Controls.SimplePlayerControl" x:Name="root"> <Grid Grid.Row="0" Grid.Column="0"> <Grid.RowDefinitions> <RowDefinition Height="*"></RowDefinition> <RowDefinition Height="*"></RowDefinition> <RowDefinition Height="10"></RowDefinition> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"></ColumnDefinition> </Grid.ColumnDefinitions> <Button Grid.Row="1" Grid.Column="0" IsEnabled="True" Clicked="Button_Clicked" Text="{Binding Source={x:Reference root}, Path=SPC_ButtonName}" x:Name="btnPlay"></Button> <toolkit:MediaElement Grid.Row="0" Grid.Column="0" ShouldShowPlaybackControls="False" ShouldAutoPlay="False" ShouldLoopPlayback="False" IsVisible="False" Volume="0.15" x:Name="plyr" Source="{Binding Source={x:Reference root}, Path=AudioSource, Mode=OneWay}" ></toolkit:MediaElement> </Grid> </ContentView>
可选优化:完善可绑定属性定义
给可绑定属性添加默认值,让代码更健壮(非必须,但推荐):
public partial class SimplePlayerControl : ContentView { public static readonly BindableProperty AudioSourceProperty = BindableProperty.Create( nameof(AudioSource), typeof(MediaSource), typeof(SimplePlayerControl), defaultValue: null); public MediaSource AudioSource { get { return (MediaSource)GetValue(AudioSourceProperty); } set { SetValue(AudioSourceProperty, value); } } public static readonly BindableProperty SPC_ButtonNameProperty = BindableProperty.Create( nameof(SPC_ButtonName), typeof(string), typeof(SimplePlayerControl), defaultValue: string.Empty); public string SPC_ButtonName { get { return (string)GetValue(SPC_ButtonNameProperty); } set { SetValue(SPC_ButtonNameProperty, value); } } public SimplePlayerControl() { InitializeComponent(); // 不要设置BindingContext = this,避免破坏外部绑定 } private void Button_Clicked(object sender, EventArgs e) { plyr.Play(); } }
验证效果
修改后,外部调用的代码无需改动:
<customcontrols:SimplePlayerControl AudioSource="{Binding PlayerSource, Mode=OneWay}" SPC_ButtonName="Play the mp3"></customcontrols:SimplePlayerControl>
此时按钮会正常显示文本,MediaElement也能获取到正确的媒体源,点击按钮即可播放。
内容的提问来源于stack exchange,提问作者Skyraider
相关产品推荐
相关产品推荐

