XamarinCommunityToolkit icon indicating copy to clipboard operation
XamarinCommunityToolkit copied to clipboard

[Bug] RequiredStringValidationBehavior stays invalid when it should be valid

Open CostasAthan opened this issue 1 year ago • 7 comments

Description

RequiredStringValidationBehavior stays always invalid

Steps to Reproduce

StackLayout myLayout = new StackLayout
{ 
    Children =
    {
        new Entry(),

        new Entry(),
                   
        new Entry()
    }
};

myLayout.Children.OfType<Entry>().ElementAt(2).Behaviors.Add
(
     new RequiredStringValidationBehavior
      {
           RequiredString = myLayout.Children.OfType<Entry>().ElementAt(1).Text,
           InvalidStyle = invalidEntryStyle,
           Flags = ValidationFlags.ValidateOnValueChanging
      }
);

Expected Behavior

  1. Run the aforementioned code.
  2. Enter the same strings in both the second and the third Entries.

Actual Behavior

The RequiredStringValidationBehavior stays invalid

Basic Information

  • Version with issue: XamarinCommunityToolkit 2.0.6

CostasAthan avatar May 08 '23 13:05 CostasAthan

I think you are not properly binding RequiredString.

At the moment you are setting RequiredString with the current value of myLayout.Children.OfType<Entry>().ElementAt(1).Text.

You should do something like this:

requiredStringValidationBehaviorReference
.SetBinding(
    RequiredStringValidationBehavior.RequiredStringProperty,
    new Binding("Text", source: myLayout.Children.OfType<Entry>().ElementAt(1))
);

For reference: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/data-binding/basic-bindings#bindings-without-a-binding-context

FedericoNembrini avatar May 10 '23 14:05 FedericoNembrini

At the moment you are setting RequiredString with the current value of myLayout.Children.OfType<Entry>().ElementAt(1).Text

Yes. Isn't RequiredString the string that will be compared to the value provided in the third entry? When both the second and the third entries have as a value exactly the same string, shouldn't the above code return a valid state for the third one?

CostasAthan avatar May 10 '23 15:05 CostasAthan

When you are executing this?

myLayout.Children.OfType<Entry>().ElementAt(2).Behaviors.Add
(
     new RequiredStringValidationBehavior
      {
           RequiredString = myLayout.Children.OfType<Entry>().ElementAt(1).Text,
           InvalidStyle = invalidEntryStyle,
           Flags = ValidationFlags.ValidateOnValueChanging
      }
);

myLayout.Children.OfType<Entry>().ElementAt(1).Text is already set with the desired value? Otherwise, you are setting RequiredString to string.Empty, and since you are not binding the value, even if you change the text of the second entry, RequiredString will remain string.Empty.

FedericoNembrini avatar May 10 '23 15:05 FedericoNembrini

@FedericoNembrini

Yes, I got what you are saying!

Should the following version work though?

myLayout.Children.OfType<Entry>().ElementAt(2).Behaviors.Add
(
     new RequiredStringValidationBehavior
      {
           RequiredString = myLayout.Children.OfType<Entry>().ElementAt(1).Text,
           InvalidStyle = invalidEntryStyle,
           Flags = ValidationFlags.ValidateOnValueChanging,
           BindingContext = myLayout.Children.OfType<Entry>().ElementAt(1).Text
      }
)

It doesn't work either.

CostasAthan avatar May 10 '23 15:05 CostasAthan

No, it cannot work. You have to set the binding with .SetBinding()

FedericoNembrini avatar May 10 '23 15:05 FedericoNembrini

What's the purpose of BindingContext property then?

CostasAthan avatar May 10 '23 16:05 CostasAthan

You need to learn more about Binding and BindingContext. In simple terms the BindingContext is the object it is associated with. However, the fact remains that to tell RequiredString what property to "Bind" to, you must use SetBinding().

FedericoNembrini avatar May 10 '23 16:05 FedericoNembrini