Reputation: 105
Xamarin Forms does not bind to ContentView properties as expected.
Goal
Reuse visual elements whenever possible to maintain consistent style and decrease duplicate code.
Expected
BindableProperty in the ContentView should be set with MyText="{Binding Text}"
and be rendered as shown here:
Actual
The BindableProperty is not set as expected and is rendered as shown here:
Environment
Solution code has been uploaded to GitHub.
<CollectionView x:Name="ItemsListView" ItemsSource="{Binding Items}" SelectionMode="None">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="model:Item">
<Grid ColumnDefinitions="*,*" RowDefinitions="Auto,Auto" BackgroundColor="LightGray">
<!-- ItemsPage Binding -->
<Label Grid.Column="0" Text="{Binding Text}" BackgroundColor="DarkGray" />
<!-- ContentView Static Text-->
<cv:MyContentView Grid.Column="1" MyText="Text!" />
<!-- ContentView Binding -->
<cv:MyContentView Grid.Column="2" MyText="{Binding Text}" />
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<Label Text="{Binding MyText}" BackgroundColor="DarkBlue" TextColor="White" />
public static readonly BindableProperty MyTextProperty =
BindableProperty.Create(nameof(MyText), typeof(string), typeof(MyContentView),
default(string), propertyChanged: MyTextChanged);
private static void MyTextChanged(BindableObject bindable, object oldValue, object newValue)
{
// Called 7 times on first load (there are only 5 items in the MockDataStore).
// Called 1 time when performing a RefreshView/LoadItemsCommand.
Debug.WriteLine($"MyTextChanged, oldValue: {oldValue}, newValue: {newValue}");
((MyContentView)bindable).MyTextChanged((string)oldValue, (string)newValue);
}
private void MyTextChanged(string oldValue, string newValue)
{
MyText = newValue;
}
public string MyText
{
get
{
return (string)GetValue(MyTextProperty);
}
private set
{
SetValue(MyTextProperty, value);
}
}
Application Output
MyTextChanged, oldValue: , newValue: Text!
MyTextChanged, oldValue: , newValue: Text!
MyTextChanged, oldValue: , newValue: Text!
MyTextChanged, oldValue: , newValue: Text!
MyTextChanged, oldValue: , newValue: Text!
MyTextChanged, oldValue: , newValue: Text!
MyTextChanged, oldValue: , newValue: Text!
Upvotes: 1
Views: 452
Reputation: 837
Remove binding context in constructor
public MyContentView()
{
InitializeComponent();
//BindingContext = this;
}
Add Source to your binding
<ContentView
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="BindingIssue.ContentViews.MyContentView"
x:Name="myContentView">
<ContentView.Content>
<Label Text="{Binding MyText,Source={x:Reference myContentView}}" BackgroundColor="DarkBlue" TextColor="White"/>
</ContentView.Content>
</ContentView>
Upvotes: 2