在父项中设置绑定时,Xamarin.Forms 绑定到自定义控件不起作用
Posted
技术标签:
【中文标题】在父项中设置绑定时,Xamarin.Forms 绑定到自定义控件不起作用【英文标题】:Xamarin.Forms Binding to Custom Control Not Working When Binding Is Set In Parent 【发布时间】:2019-12-10 19:37:39 【问题描述】:我正在尝试创建一个简单的 Xamarin.Forms 自定义控件,但遇到了绑定问题。
这是我最初的自定义控件:
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="CubisMobile.Controls.TestControl"
x:Name="TestControlView">
<Label Text="Binding TestText" />
public partial class TestControl : ContentView
public static readonly BindableProperty TestTextProperty = BindableProperty.Create(nameof(TestText), typeof(string), typeof(TestControl));
public string TestText
get return (string)GetValue(TestTextProperty);
set SetValue(TestTextProperty, value);
public TestControl()
InitializeComponent();
BindingContext = this;
我试图以这种方式使用它:
...
<StackLayout>
<controls:TestControl TestText="Binding Title" />
<Label Text="Binding Title" />
</StackLayout>
...
我添加了第二个标签来测试 Title 属性是否可以正常工作,并且确实可以。
但是文本不会显示在自定义控件上。当我设置像TestText="Testing"
这样的常量值时,它可以正常工作。我在 *** 上找到了this answer,尝试了以下方法,但也没有用(自定义控件 XAML):
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="CubisMobile.Controls.TestControl"
x:Name="TestControlView">
<Label Text="Binding Source=x:Reference TestControlView, Path=TestText" />
我真的不明白为什么这个绑定不起作用。
【问题讨论】:
【参考方案1】:你找到的答案很好,我在我的图书馆里也是这样:
<tabs:TabItem x:Class="Sharpnado.Presentation.Forms.CustomViews.Tabs.UnderlinedTabItem"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:tabs="clr-namespace:Sharpnado.Presentation.Forms.CustomViews.Tabs;assembly=Sharpnado.Presentation.Forms"
x:Name="RootLayout">
<ContentView.Content>
<Grid BackgroundColor="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Label Style="StaticResource TabTextHeader"
FontFamily="Binding Source=x:Reference RootLayout, Path=FontFamily"
FontSize="Binding Source=x:Reference RootLayout, Path=LabelSize"
Text="Binding Source=x:Reference RootLayout, Path=Label"
TextColor="Binding Source=x:Reference RootLayout, Path=UnselectedLabelColor">
以及背后的代码:
public static readonly BindableProperty FontFamilyProperty = BindableProperty.Create(
nameof(FontFamily),
typeof(string),
typeof(TabItem),
null,
BindingMode.OneWay);
public string FontFamily
get => (string)GetValue(FontFamilyProperty);
set => SetValue(FontFamilyProperty, value);
我在您显示的代码中看到的唯一问题是BindingContext
的设置:
public TestControl()
InitializeComponent();
BindingContext = this; // Remove this line
【讨论】:
我正在尝试使用你的库,我觉得很难理解,没有一个简单的例子来说明如何使用它,更多的是你是如何制作它的。一些代码 sn-ps 没有显示完整的代码,最终不知道哪个是哪个,例如我不知道这个 github.com/roubachof/Sharpnado.Presentation.Forms/wiki/… 中的细节是什么 伙计,来吧,这里有一个完整的示例应用程序:github.com/roubachof/Xamarin-Forms-Practices 设法让它工作.. 玩弄它感谢这个。想在 shell 中使用它,最好的方法是什么?【参考方案2】:我已经测试了你的代码,我们需要注意几个地方:
1.假设ContentView的类名是TestControl
,你可以试试你说的下面的代码:
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="CustomeViewApp1.controls.TestControl"
x:Name="TestControlView"
>
<ContentView.Content>
<Label Text="Binding Source=x:Reference TestControlView, Path=TestText" />
</ContentView.Content>
2.删除TestControl.xaml.cs
中的代码BindingContext = this;
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class TestControl : ContentView
public static readonly BindableProperty TestTextProperty = BindableProperty.Create(nameof(TestText), typeof(string), typeof(TestControl));
public string TestText
get return (string)GetValue(TestTextProperty);
set SetValue(TestTextProperty, value);
public TestControl()
InitializeComponent();
//BindingContext = this;
我使用的测试xaml如下:
<StackLayout Orientation="Horizontal" HorizontalOptions="Center">
<controls:TestControl TestText="Binding Title" VerticalOptions="Center"/>
<Label Text="Binding Type" FontSize="Medium" TextColor="#F0BB7F"
FontAttributes="Bold" VerticalOptions="Center"/>
</StackLayout>
您可以查看我测试的完整演示 here。
【讨论】:
【参考方案3】:提供的答案工作正常。但是,这些要求您手动设置每个属性的绑定源。如果很多属性需要绑定,这可能会变得乏味。
一种更简单的方法是覆盖框架公开的 OnChildAdded 事件并在那里设置绑定上下文。这将自动为添加的任何子设置绑定上下文。
要做到这一点,请按以下步骤操作:
在代码隐藏文件中添加以下方法:
protected override void OnChildAdded(Xamarin.Forms.Element child) base.OnChildAdded(child); //必须调用才能应用基本实现 child.BindingContext = this; //这为添加的孩子设置绑定上下文
在您的 xaml 中将您的控件绑定到公共可绑定属性。例如:
【讨论】:
以上是关于在父项中设置绑定时,Xamarin.Forms 绑定到自定义控件不起作用的主要内容,如果未能解决你的问题,请参考以下文章
Xamarin.Forms:有没有办法在xaml中设置派生样式的默认字体(系列)?
在Xamarin Forms中设置TableView宽度和高度
如何在Xamarin Forms中设置自动日/夜模式谷歌地图