Xamarin Forms how to add behaviors to custom control

I have created a custom control,which is a ContentView with a Label and an Entry

The xaml of the custom controls looks like this:

<Label Text="{Binding Source={x:Reference ValidationControl}, Path=Caption}"/>
<Entry Text="{Binding Source={x:Reference ValidationControl}, Path=Value, Mode=TwoWay}" />

The code behind of the custom control looks like this:

public static readonly BindableProperty CaptionProperty = BindableProperty.Create(
    nameof(Caption), typeof(string), typeof(ValidationEntry), default(string));

public string Caption
{
    get => (string)GetValue(CaptionProperty);
    set => SetValue(CaptionProperty, value);
}

public static readonly BindableProperty ValueProperty = BindableProperty.Create(
    nameof(Value), typeof(string), typeof(ValidationEntry), default(string));

public string Value
{
    get => (string)GetValue(ValueProperty);
    set => SetValue(ValueProperty, value);
}

I’m using the custom control in the following way

<controls:ValidationEntry Caption=”Name:” Value="{Binding FullName, Mode=TwoWay}" />

My question is how to add behaviors to the custom control?
I would like to add them in the place that I’m using the control. i.e.

<controls:ValidationEntry Caption="Name:"
                          Value="{Binding FullName, Mode=TwoWay}">
    <controls:ValidationEntry.EntryBehaviors>
        <behaviors:EntryLengthValidatorBehavior IgnoreSpaces="True"/>
    </controls:ValidationEntry.EntryBehaviors>
</controls:ValidationEntry>

Answers

  • ColeXColeX Member, Xamarin Team Xamurai

    What's the problem you're facing ? What exactly do you want to achieve ?

  • DimitrisMylonasDimitrisMylonas USMember ✭✭

    Add behaviors to the custom control that I can apply to the Entry.
    I wasn't able to find a way to populate the IList<Behaviors> of the Entry inside the custom control by adding the behaviors in the custom control.

  • ColeXColeX Member, Xamarin Team Xamurai

    Create behavior for your custom control , and find the Entry inside it ..

    class CustomBehavior : Behavior<ValidationEntry>
        {
            protected override void OnAttachedTo(ValidationEntry view)
            {
                StackLayout stack = view.Content as StackLayout;
                Entry e = stack.Children[0] as Entry;
                //handle the logic
    
                base.OnAttachedTo(view);
            }
        }
    
  • DimitrisMylonasDimitrisMylonas USMember ✭✭
    edited July 15

    So you mean, that there is no way to add behaviors to my custom control like I do with an Entry?
    You mean, that if I have a behavior for an Entry and I need it also for my custom control then I cannot reuse it and I should create a different behavior doing the same thing but for my custom control?
    You mean that if I have another custom control with 2 Entries (i.e. phone number with National prefix and the phone number) and I need the same behavior then I should create a third for that particular custom control?

  • ColeXColeX Member, Xamarin Team Xamurai
    edited July 15

    Why don't you use behavior with Entry in your custom control directly?

    // inside your control 
    <Label Text="{Binding Source={x:Reference ValidationControl}, Path=Caption}"/>
    <Entry Text="{Binding Source={x:Reference ValidationControl}, Path=Value, Mode=TwoWay}">
            <Entry.Behaviors>
                <local:NumericValidationBehavior />
            </Entry.Behaviors>
    </Entry>
    

    local:NumericValidationBehavior is Behavior is for Entry , and it is reusable.

  • DimitrisMylonasDimitrisMylonas USMember ✭✭

    I made the custom control in order to use it in multiple cases. Different cases need different behaviors.
    As a result, I would like to add the behaviors that I want depending on the use of the custom control.
    That is the reason that we can add behaviors to a simple Entry control depending on the situation.

  • ColeXColeX Member, Xamarin Team Xamurai
    edited July 15

    I suggest you handle the logic in custom renderer code behind.

            if (A)
            {
                entry.Behaviors.Add(new BehaviorA());
            }
            else if (B)
            {
                entry.Behaviors.Add(new BehaviorB());
            }
            else 
            {
                entry.Behaviors.Add(new BehaviorC());
            }
    
  • DimitrisMylonasDimitrisMylonas USMember ✭✭

    What is the if (A)?
    Don't you think that this is a very cumbersome and unpractical solution that also needs a lot of maintenance?

  • ColeXColeX Member, Xamarin Team Xamurai

    Behavior A is created and used for Control A , you can't add Behavior of Entry on your custom control .

  • IeuanWalkerIeuanWalker USMember ✭✭

    Did you ever find a solution for this?

  • DimitrisMylonasDimitrisMylonas USMember ✭✭

    @IeuanWalker ...not a good one… but I realized also that I made some mistakes.
    Firstly, just to describe the solution, is to create a bindable property of type bool to specify if I want to attach the behavior (or the effect)
    On property change of the bindable property I add the behavior by code.
    It’s not a pretty solution. I can re-use the behaviors or the effects which is good but I need to create a few bindable properties… which is not good.
    The default value of the bindable property is false so my XAML is not that verbose. In my case I only had 2 behaviors and 1 effect so it worked for me.
    I think that one mistake that I did is that the behaviors (or the effects) should be for the ContentView that contains the entry instead of the entry.

Sign In or Register to comment.