I have a problem binding data in a custom view in Xamarin forms to the view model of the containing page.
My Custom View is very simple, a pair of labels representin
I was able to get this to work by doing
public KeyValueView()
{
InitializeComponent();
this.VerticalOptions = LayoutOptions.Start;
this.Content.BindingContext = this;
}
and then doing this in the xaml.cs for the view you're using the custom view in:
public ParentView()
{
InitializeComponent();
BindingContext = this;
}
For an Entry field, which gave me problems, I had to make sure the defaultBindingMode parameter was set to TwoWay.
Don't assign bindings internally inside custom controls. Use this:
public partial class KeyValueView : ContentView
{
public KeyValueView()
{
InitializeComponent();
this.VerticalOptions = LayoutOptions.Start;
}
public static readonly BindableProperty ValueProperty =
BindableProperty.Create<KeyValueView, string>(w => w.Value, default(string));
public string Value
{
get {return (string)GetValue(ValueProperty);}
set {SetValue(ValueProperty, value);}
}
public static readonly BindableProperty KeyProperty =
BindableProperty.Create<KeyValueView, string>(w => w.Key, default(string));
public string Key
{
get {return (string)GetValue(KeyProperty);}
set {SetValue(KeyProperty, value);}
}
protected override void OnPropertyChanged(string propertyName)
{
base.OnPropertyChanged(propertyName);
if (propertyName == ValueProperty.PropertyName)
{
ValueLabel.Text = Value;
}
if (propertyName == KeyProperty.PropertyName)
{
KeyLabel.Text = Key;
}
}
}
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="KeyValueView">
<Grid VerticalOptions="Start">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Label x:Name="KeyLabel" Grid.Column="0" HorizontalOptions="Start" />
<Label x:Name="ValueLabel" Grid.Column="1" HorizontalOptions="EndAndExpand" />
</Grid>
</ContentView>
Treat properties (eg. Value) as references to BindableProperty (ValueProperty). If you do something inside Value setter BindableProperty won't be notified about it AND opposite if you do something with BindableProperty (assign/change ValueProperty) - property Value setter won't be called.
If you want to handle PropertyChanged you have an override for that (OnPropertyChanged) or Actions (as additional parameters when creating BindableProperty).