I have a custom control, which is basically a XML wrapper around another custom control, with its own CustomRenderer
.
Custom Control, basically a Wrapper XAML for another custom control
<?xml version="1.0" encoding="UTF-8" ?>
<ContentView
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Test.Controls.TitleAndEntry"
xmlns:renderers="clr-namespace:Test.Renderers">
<StackLayout>
<Label
FontAttributes="Bold"
Style="{StaticResource TitleSemiBoldBlackLabel}"/>
<renderers:EntryBottomLine
x:Name="myEntry"
PlaceholderColor="{StaticResource PrimarySolidGrayColor}"
IsPassword="False"
TextColor="{StaticResource BlackColor}"/>
</StackLayout>
</ContentView>
Custom Control Wrapper Code-Behind
public partial class TitleAndEntry : ContentView
{
public TitleAndEntry()
{
InitializeComponent();
}
// Other BindableProperties & code
public static BindableProperty TextEntryChangedProperty = BindableProperty.Create(
nameof(TextEntryChanged), typeof(EventHandler<TextChangedEventArgs>), typeof(TitleAndEntry), null,
propertyChanged: OnTextEntryChanged);
public EventHandler<TextChangedEventArgs> TextEntryChanged
{
get
{
return (EventHandler<TextChangedEventArgs>)GetValue(TextEntryChangedProperty);
}
set
{
SetValue(TextEntryChangedProperty, value);
}
}
private static void OnTextEntryChanged(BindableObject bindable, object oldVal, object newVal)
{
var titleAndEntry = (TitleAndEntry)bindable;
titleAndEntry.myEntry.TextChanged += (EventHandler<TextChangedEventArgs>)newVal;
}
}
}
XAML on the page where I use the custom control
<ctrl:TitleAndEntry
x:Name="user"
Margin="{StaticResource NormalTopPadding}"
TextLabel="{x:Static local:AppResources.User}"
TextChanged="OnMyTextChanged"/>
Code-behind of that page
private void OnMyTextChanged(object sender, TextChangedEventArgs e)
{
// Call to Viewmodel
}
I get this error:
Xamarin Forms No property, bindable property, or event found for 'TextChanged', or mismatching type between value and property
I tried many suggestions, but I cannot get it to work.
I'll answer it myself:
After going back to the InputView
(which is the base class for Entry
), I noticed that TextChanged
is not a BindableProperty
, but an event.
public event EventHandler<TextChangedEventArgs> TextChanged;
So I removed the entire BindableProperty
and replaced it with:
// On the regular Text propert, call the event handler from the PropertyChanged param
public static readonly BindableProperty TextProperty =
BindableProperty.Create(
nameof(Text),
typeof(string),
typeof(TitleAndEntry),
null,
BindingMode.TwoWay,
propertyChanged: (bindable, oldValue, newValue) => ((TitleAndEntry)bindable).OnTextChanged((TitleAndEntry)bindable, (string)oldValue, (string)newValue));
public event EventHandler<TextChangedEventArgs> TextChanged;
// Simply Invoke the event with the provided args
private void OnTextChanged(TitleAndEntry bindable, string oldValue, string newValue)
{
this.TextChanged?.Invoke(bindable, new TextChangedEventArgs(oldValue, newValue));
}
Now it works as it should.