0

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.

Fred Fickleberry III
  • 2,439
  • 4
  • 34
  • 50

1 Answers1

1

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.

Fred Fickleberry III
  • 2,439
  • 4
  • 34
  • 50