0

I have a simple custom control, which I use in a ContentPage (actually a LoginPage) in my Xamarin forms app. The custom control has a property called EntryText which I am trying to bind to the LoginViewModel's Email property.

If I bind Email with the custom control's EntryText, it does not seem to work. However, if I bind Email to a normal control like Entry's Text, it does work correctly. What am I doing wrong here?

My custom control:

public class FlakeEntry2 : StackLayout { public Entry Entry; public Label ErrorLabel; public FlakeEntry2() { Entry = new Entry { }; Children.Add(Entry); ErrorLabel = new Label { FontAttributes = FontAttributes.Italic, TextColor = Color.Red, }; Children.Add(ErrorLabel); } #region Text property which I am trying to bind public static readonly BindableProperty EntryTextProperty = BindableProperty.Create( propertyName: nameof(EntryText), returnType: typeof(string), declaringType: typeof(FlakeEntry2), defaultValue: null, defaultBindingMode: BindingMode.TwoWay, propertyChanged: EntryTextPropertyChanged); public string EntryText { get { return GetValue(EntryTextProperty)?.ToString(); } set { SetValue(EntryTextProperty, value); } } private static void EntryTextPropertyChanged(BindableObject bindable, object oldValue, object newValue) { var control = (FlakeEntry2)bindable; control.Entry.Text = newValue?.ToString(); } #endregion } 

The View (LoginPage) where I try to bind looks like this:

<StackLayout Orientation="Vertical" Spacing="10"> <custom:FlakeEntry2 x:Name="Email" EntryText="{Binding Email}" /> <!--This does not work--> <Entry Text="{Binding Email}"/> <!--This works--> </StackLayout> 

Finally the ViewModel is pretty much standard and implements INotifyPropertyChanged. The Email property of which looks like:

private string _email; public string Email { get { return _email; } set { _email = value; NotifyPropertyChanged(); } } 

I have tried adding a XAML based custom control (current one is just C# based). I have tried explicitly adding BindingContext={Binding} to the custom control used in the LoginPage. I have read numerous blogs but to no avail. Can someone please point me in the right direction?

1
  • I have used MVVM and custom controls on numerous occasions in Silverlight and WPF, but Xamarin is making me pull my hair out! Commented Mar 1, 2018 at 19:18

1 Answer 1

4

I've heard there are some things a bit different between the WPF and XF bindings and even its XAML syntaxes but I don't know much about WPF.

Whatever.

How about to use cascade bindings and take control of your component avoiding exposing its inner views?

I always use this approach and works pretty fine for me, see if it fit's to you too:

public class FlakeEntry2 : StackLayout { private Entry Entry; private Label ErrorLabel; public FlakeEntry2() { Entry = new Entry { }; ErrorLabel = new Label { FontAttributes = FontAttributes.Italic, TextColor = Color.Red, }; this.Entry.SetBinding(Entry.TextProperty, new Binding(nameof(EntryText), source: this)); // You'll need to do the same to label's and other properties you need expose, but you get rid of the 'OnChanged' methods Children.Add(Entry); Children.Add(ErrorLabel); } #region Text property which I am trying to bind public static readonly BindableProperty EntryTextProperty = BindableProperty.Create( propertyName: nameof(EntryText), returnType: typeof(string), declaringType: typeof(FlakeEntry2), defaultValue: null, defaultBindingMode: BindingMode.TwoWay); public string EntryText { get { return GetValue(EntryTextProperty)?.ToString(); } set { SetValue(EntryTextProperty, value); } } #endregion } 

Nothing on your XAML nor VM should be changed.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! This works!! What is insane is that when I had used xaml for the custom control, I did try to bind the Entry.Text and EntryTextproperties. It just did not work. but when I do the same thing from the code behind it works.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.