Reputation: 81
How do I set a binding value as a parameter on a behavior in Xamarin Forms?
When I do this I get: Error. No property, bindable property, or event found for 'InputValue', or mismatching type between value and property.
XAML:
<Label Grid.Column="0" x:Name="player" FontSize="Small" VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand"
Text="{Binding FormattedName}" >
<Label.Behaviors>
<local:ColorTextLabelBehavior MaxInputValue="100" MinInputValue="0" InputValue="{Binding Happiness}" />
</Label.Behaviors>
</Label>
C#:
public class ColorTextLabelBehavior : Behavior<Label>
{
public static readonly BindableProperty MaxValue = BindableProperty.Create("MaxValue", typeof(int), typeof(ColorTextLabelBehavior), defaultValue: 100);
public static readonly BindableProperty MinValue = BindableProperty.Create("MinValue", typeof(int), typeof(ColorTextLabelBehavior), defaultValue: 0);
public static readonly BindableProperty ActualValue = BindableProperty.Create("ActualValue", typeof(int), typeof(ColorTextLabelBehavior), defaultValue: 100);
public int MaxInputValue
{
get { return (int)GetValue(MaxValue); }
set { SetValue(MaxValue, value); }
}
public int MinInputValue
{
get { return (int)GetValue(MinValue); }
set { SetValue(MinValue, value); }
}
public int InputValue
{
get { return (int)GetValue(ActualValue); }
set { SetValue(ActualValue, value); }
}
void HandleTextChanged(object sender, PropertyChangedEventArgs e)
{
try
{
float percent = ((float)InputValue - (float)MinInputValue) / ((float)MaxInputValue - (float)MinInputValue);
double resultRed = Color.Red.R + percent * (Color.Green.R - Color.Red.R);
double resultGreen = Color.Red.G + percent * (Color.Green.G - Color.Red.G);
double resultBlue = Color.Red.B + percent * (Color.Green.B - Color.Red.B);
((Label)sender).TextColor = new Color(resultRed, resultGreen, resultBlue);
}
catch (Exception)
{
}
}
protected override void OnAttachedTo(BindableObject bindable)
{
bindable.PropertyChanged += HandleTextChanged;
}
protected override void OnDetachingFrom(BindableObject bindable)
{
bindable.PropertyChanged += HandleTextChanged;
}
}
If I hard code a value for 'InputValue' this works, but I want to be able to send a binding so that it will auto color the text.
Note this is in a listview if that matters.
Please help, I've been stuck on this and can't find any answers. I'm open to other alternatives to implementing this as well.
Thanks!!
Upvotes: 3
Views: 1965
Reputation: 6088
I believe that the exact naming is important and that the BindableProperty
has to have the name of the actual property with "Property" appended to the end. From the docs:
The naming convention for bindable properties is that the bindable property identifier must match the property name specified in the Create method, with "Property" appended to it.
So I believe you want something like this:
public static readonly BindableProperty MaxInputValueProperty = BindableProperty.Create(nameof(MaxInputValue), typeof(int), typeof(ColorTextLabelBehavior), defaultValue: 100);
public static readonly BindableProperty MinInputValueProperty = BindableProperty.Create(nameof(MinInputValue), typeof(int), typeof(ColorTextLabelBehavior), defaultValue: 0);
public static readonly BindableProperty InputValueProperty = BindableProperty.Create(nameof(InputValue), typeof(int), typeof(ColorTextLabelBehavior), defaultValue: 100);
public int MaxInputValue
{
get { return (int)GetValue(MaxValue); }
set { SetValue(MaxValue, value); }
}
public int MinInputValue
{
get { return (int)GetValue(MinValue); }
set { SetValue(MinValue, value); }
}
public int InputValue
{
get { return (int)GetValue(ActualValue); }
set { SetValue(ActualValue, value); }
}
Upvotes: 2
Reputation: 16459
Well the problem is quite simple
if you check your BindableProperty
for ActualValue
:
public int InputValue
{
get { return (int)GetValue(ActualValue); }
set { SetValue(ActualValue, value); }
}
public static readonly BindableProperty ActualValue = BindableProperty.Create("ActualValue", typeof(int), typeof(ColorTextLabelBehavior), defaultValue: 100);
You are setting the name of the property as ActualValue
when it should be the name of the associated property and not the Binding field hence your property should be something like this:
public static readonly BindableProperty ActualValue = BindableProperty.Create(nameof(InputValue), typeof(int), typeof(ColorTextLabelBehavior), defaultValue: 100);
public int InputValue
{
get { return (int)GetValue(ActualValue); }
set { SetValue(ActualValue, value); }
}
Correct the same for the other two properties as well.
also note nameof(InputValue)
is the same as "InputValue" and using nameof()
is the standard way of doing it
Upvotes: 1