【问题标题】:Xamarin.Forms Binding to Custom Control Not Working When Binding Is Set In Parent在父项中设置绑定时,Xamarin.Forms 绑定到自定义控件不起作用
【发布时间】: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" 这样的常量值时,它可以正常工作。我在 StackOverflow 上找到了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}" />

我真的不明白为什么这个绑定不起作用。

【问题讨论】:

    标签: c# xaml xamarin xamarin.forms binding


    【解决方案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 事件并在那里设置绑定上下文。这将自动为添加的任何子设置绑定上下文。

      要做到这一点,请按以下步骤操作:

      1. 在代码隐藏文件中添加以下方法:

        protected override void OnChildAdded(Xamarin.Forms.Element child) { base.OnChildAdded(child); //必须调用才能应用基本实现 child.BindingContext = this; //这为添加的孩子设置绑定上下文 }

      2. 在您的 xaml 中将您的控件绑定到公共可绑定属性。例如:

      【讨论】:

        猜你喜欢
        • 2020-02-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-12
        • 2021-02-18
        • 2019-12-26
        • 2018-02-17
        • 1970-01-01
        相关资源
        最近更新 更多