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

.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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 05:25:37