这里是主页,经典。
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:view="clr-namespace:SuperLabelApp.Resources.Views"
x:Class="SuperLabelApp.MainPage">
<view:SuperLabel Text="Hello, World"/>
</ContentPage>
namespace SuperLabelApp;
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
}
SuperLabel 有一个可绑定的 Text 属性,我希望他将其传递给 SuperLabelChild,以便其标签使用主页中的值进行更新。
<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:view="clr-namespace:SuperLabelApp.Resources.Views"
x:Class="SuperLabelApp.Resources.Views.SuperLabel">
<view:SuperLabelChild Text="{Binding Text}" />
</ContentView>
namespace SuperLabelApp.Resources.Views;
public partial class SuperLabel : ContentView
{
#region [Constructor]
public SuperLabel()
{
this.InitializeComponent();
this.BindingContext = this;
}
#endregion
#region [Bindable Properties]
public static readonly BindableProperty TextProperty = BindableProperty.Create(
nameof(Text),
typeof(string),
typeof(SuperLabel),
default(string),
propertyChanged: onchanged
);
#endregion
#region [Properties]
public string Text
{
get => (string)this.GetValue(TextProperty);
set => this.SetValue(TextProperty, value);
}
#endregion
static void onchanged(BindableObject obj, object oldValue, object newValue)
{
Console.WriteLine("Debug Super Label");
}
}
<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="SuperLabelApp.Resources.Views.SuperLabelChild">
<Label Text="{Binding Text}" />
</ContentView>
namespace SuperLabelApp.Resources.Views;
public partial class SuperLabelChild : ContentView
{
#region [Constructor]
public SuperLabelChild()
{
this.InitializeComponent();
this.BindingContext = this;
}
#endregion
#region [Bindable Properties]
public static readonly BindableProperty TextProperty = BindableProperty.Create(
nameof(Text),
typeof(string),
typeof(SuperLabelChild),
default(string),
propertyChanged: onchanged
);
#endregion
#region [Properties]
public string Text
{
get => (string)this.GetValue(TextProperty);
set => this.SetValue(TextProperty, value);
}
#endregion
static void onchanged(BindableObject obj, object oldValue, object newValue)
{
Console.WriteLine("Debug Super Label Child");
}
}
MainPage 中的值永远不会到达 SuperLabelChild。当我更改“Hello, World”时,会触发 SuperLabel 的 onchanged 事件,但不会触发 SuperLabelChild 中的事件。 如果我将 SuperLabel.xaml 的绑定更改为“Hi”等文本,我会到达 onchanged 事件,并且 UI 中的标签将更改为“Hi”。
我知道我可能做错了什么,但为什么它可以与以下绑定一起使用:
SuperLabel->SuperLabelChild->Label,
但不是为了
MainPage->SuperLabel->SuperLabelChild
我错过了什么吗?
请注意,这个示例很简单,只是我遇到的实际问题的复制。
我尝试更改绑定、更改顺序。 以两种方式制作 BindableProperty。
我期望 SuperLabel 的绑定能够通知其对 SuperLabelChild 的更改,但事实并非如此。
我知道我可以使用 c# 来更改标签的值,但我想了解绑定是如何工作的,并且很难调试。
您可以使用 控件模板,然后使用
TemplateBinding
传递参数,这会将 ControlTemplate
中元素的属性绑定到由模板化自定义控件或模板化页面定义的公共属性。
因此更改您的SuperLabelChild.xaml,如下所示:
<ContentView.ControlTemplate>
<ControlTemplate>
<VerticalStackLayout>
<Label Text="{TemplateBinding Text}" />
<ContentPresenter/>
</VerticalStackLayout>
</ControlTemplate>
</ContentView.ControlTemplate>
更多详情可以参考使用TemplateBinding传递参数。
做一些改变,它就会起作用。
对于SuperLabel.xaml,
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
...
x:Name="superLabel">
<view:SuperLabelChild Text="{Binding Text,Source={x:Reference superLabel}}" />
</ContentView>
对于 SuperLabelChild.xaml,
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
...
x:Name="superLabelChild">
<Label Text="{Binding Text,Source={x:Reference superLabelChild}}" />
</ContentView>
此外,您不必在这两个文件中设置
this.BindingContext=this
。
更多信息,您可以参考.NET MAUI ContentView。