Binding with CustomControl is not working

1

I created a CustomControl but creating a BindingProperty I can not do a binding

Custom Control XAML Code

<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         x:Class="CustomControls.Controls.CustomEditor">
    <Editor x:Name="edt" Text="{Binding Text, Mode=TwoWay}" />
</ContentView>

CustomControl CS Code

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class CustomEditor : ContentView
{
    public CustomEditor ()
    {
        InitializeComponent ();
        this.BindingContext = this;
    }

    public static readonly BindableProperty TextProperty = BindableProperty.Create(
       propertyName: nameof(Text),
       returnType: typeof(string),
       declaringType: typeof(CustomEditor),
       defaultValue: "",
       defaultBindingMode: BindingMode.TwoWay,
       propertyChanged: (b, o, n) =>
       {
           if (b is CustomEditor view)
               view.edt.Text = n.ToString();
       });        

    public string Text
    {
        get => (string)GetValue(TextProperty);
        set
        {
            SetValue(TextProperty, value);
            base.OnPropertyChanged(nameof(Text));
        }
    }
}

MainPage XAML that consumes CustomControl

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:local="clr-namespace:CustomControls"
         xmlns:controls="clr-namespace:CustomControls.Controls"
         x:Class="CustomControls.MainPage">
    <StackLayout Padding="10">
        <Label Text="{Binding Email}"/>
        <Editor x:Name="txtTeste" Text="{Binding Email}"/>
        <controls:CustomEditor Text="{Binding Email, Mode=TwoWay}"/>
    </StackLayout>
</ContentPage>

MainPage CS

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
        BindingContext = this;
        this.Email = "[email protected]";
    }

    private string _email;

    public string Email
    {
        get { return _email; }
        set { _email = value; base.OnPropertyChanged(nameof(Email)); }
    }
}

In MainPage in the customControl if you start with a HardCode it already opens the app with the Editor filled however any change in the Email property it does not reflect in the Editor and if it changes the value of the Editor it does not reflect in the email property, Situation?

    
asked by anonymous 06.12.2018 / 20:47

1 answer

1

With this article CustomControls Xamarin Forms I was able to solve my problem, component The end is gone.

XAML

<?xml version="1.0" encoding="UTF-8"?>
<Grid xmlns="http://xamarin.com/schemas/2014/forms" 
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        x:Class="Camareira.Controls.FormEntry" 
        HorizontalOptions="FillAndExpand">
    <Grid.RowDefinitions>
        <RowDefinition Height="25"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Label x:Name="label" Grid.Row="0"/>
    <Entry x:Name="entry" Grid.Row="1"/>
</Grid>

.CS

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class FormEntry : Grid
{
    public FormEntry ()
    {
        InitializeComponent ();
        entry.TextChanged += (s, e) =>
        {
            Text = e.NewTextValue;
        };
    }

    public static readonly BindableProperty TitleProperty = BindableProperty.Create(
        nameof(Title),
        typeof(string),
        typeof(FormEntry),
        null,
        BindingMode.OneWay);
    public string Title
    {
        get => (string)GetValue(TitleProperty);
        set => SetValue(TitleProperty, value);
    }

    public static readonly BindableProperty TextProperty = BindableProperty.Create(
        nameof(Text),
        typeof(string),
        typeof(FormEntry),
        null,
        BindingMode.TwoWay);
    public string Text
    {
        get => (string)GetValue(TextProperty);
        set => SetValue(TextProperty, value);
    }

    public static readonly BindableProperty PlaceholderProperty = BindableProperty.Create(
        nameof(Placeholder),
        typeof(string),
        typeof(FormEntry),
        null,
        BindingMode.TwoWay);
    public string Placeholder
    {
        get => (string)GetValue(PlaceholderProperty);
        set => SetValue(PlaceholderProperty, value);
    }

    protected override void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        base.OnPropertyChanged(propertyName);
        switch (propertyName)
        {
            case nameof(Title):
                label.Text = Title;
                break;
            case nameof(Text):
                entry.Text = Text;
                label.IsVisible = !String.IsNullOrEmpty(Text);
                break;
            case nameof(Placeholder):
                entry.Placeholder = Placeholder;
                break;
        }
    }
}
    
07.12.2018 / 17:37