Binding with Customcontrol is not working

Asked

Viewed 59 times

1

I created a Customcontrol but creating a Bindingproperty I cannot perform 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>

CS code of Customcontrol

[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 customControl if I start with a Hardcode it already opens the app with Editor filled but any change in the property Email it does not reflect in the Editor and if I change the value of the Editor it does not reflect in the property email, it is possible to use Binding in this Situation?

1 answer

1

With that article Customcontrols Xamarin Forms I managed to solve my problem, the final component was.

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;
        }
    }
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.