简体   繁体   中英

Bindable Entry is not working inside custom control in Xamarin.forms?

I have an entry field inside custom control. I've created bindable property for the same.

Here's my code:

public string MyEntry
    {
        get => (string)GetValue(MyEntryProperty);
        set => SetValue(MyEntryProperty, value);
    }
    public static BindableProperty MyEntryProperty = BindableProperty.Create(
                                             propertyName: "MyEntry",
                                             returnType: typeof(string),
                                             declaringType: typeof(MyView),
                                             defaultValue: string.Empty,
                                             defaultBindingMode: BindingMode.TwoWay,
                                             propertyChanged:MyEntryPropertyChanged );


 public static void MyEntryPropertyChanged(BindableObject bindable, object oldValue, object newValue)
    {
       var cView = (MyView)bindable;
       cView.myent.Text = (string)newValue;
   }

Then on my actual view xaml:

<MyView MyEntry={Binding Something}/>

But it's not working.? Any suggestions?

Maybe you do not set the binding correctly. I make a code sample for your reference.

MyView:

<?xml version="1.0" encoding="utf-8" ?>
<ContentView
x:Class="XamarinDemo.Custom_Control.MyView"
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">

<StackLayout>
    <Entry
        x:Name="myent"
        HorizontalOptions="CenterAndExpand"
        Text="Welcome to Xamarin.Forms!"
        VerticalOptions="CenterAndExpand" />
    <Button />
</StackLayout>

</ContentView>

Code Behind: Same with yours.

 public partial class MyView : ContentView
{
    public MyView()
    {
        InitializeComponent();
    }
    public string MyEntry
    {
        get => (string)GetValue(MyEntryProperty);
        set => SetValue(MyEntryProperty, value);
    }
    public static BindableProperty MyEntryProperty = BindableProperty.Create(
                                             propertyName: "MyEntry",
                                             returnType: typeof(string),
                                             declaringType: typeof(MyView),
                                             defaultValue: string.Empty,
                                             defaultBindingMode: BindingMode.TwoWay,
                                             propertyChanged: MyEntryPropertyChanged);


    public static void MyEntryPropertyChanged(BindableObject bindable, object oldValue, object newValue)
    {
        var cView = (MyView)bindable;
        cView.myent.Text = (string)newValue;
    }
}

Usage: Page1.xaml

 <ContentPage.Content>
    <StackLayout>
        <local:MyView MyEntry="{Binding Something}"></local:MyView>
    </StackLayout>
</ContentPage.Content>

Binding:

 public partial class Page1 : ContentPage
{
    public string Something { get; set; }
    public Page1()
    {
        InitializeComponent();
        Something = "Hello";
        this.BindingContext = this;
    }
}

Screenshot:

在此处输入图像描述

I have had this issue with a custom control of mine, the main problem was my binding context was not set correctly.

The way that I used to check this was

  1. I gave my control a x:name in the xaml

  2. I went to the pagename.cs (code behind) in the constructor after the InializeComponents() method I typed this

Console.WriteLine($"Control-{ControlXname.BindingContext();}");
Console.WriteLine($"Page-{this.BindingContext();}");
  1. After i excuted my code i headed to the output panel and i pressed ctrl + f to search for the word "Control-" and "Page-" only then i have found out that thier binding contexts was different.

You are only setting value to Entry, you are not reading back the changes from Entry. You have to add following in your constructor.

// ... add this in your constructor...
myent.SetBinding(Entry.TextProperty, new Binding{
    Path = "MyEntry",
    Source = this,
    Mode = BindingMode.TwoWay
});



public string MyEntry
{
    get => (string)GetValue(MyEntryProperty);
    set => SetValue(MyEntryProperty, value);
}

// remove onPropertyChanged
public static BindableProperty MyEntryProperty = BindableProperty.Create(
                                         propertyName: "MyEntry",
                                         returnType: typeof(string),
                                         declaringType: typeof(MyView),
                                         defaultValue: string.Empty,
                                         defaultBindingMode: BindingMode.TwoWay);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM