I have an enum property in the view-model and I want to make a label visible if the property value is of a specific value
States state;
public States State
{
get { return this.state; }
set
{
if (this.state != value)
{
this.state = value;
this.RaisePropertyChanged("State");
}
}
}
public enum States
{
Stopped,
Runnning
}
here's what I tried in the UI:
local:MvxBind="Visibility If(State==1, 'Visible', 'Gone')"
but it doesn't work. No error is displayed in the log.
I can make a converter but I was wondering if it's possible to do it without it.
If I modify the State property to use int instead of Enum, it works fine. I guess it has to do with how currently Enum type is handled.
In the Tibet binding addons, statements like:
If(State==1, 'Visible', 'Gone'
are not compiled because of iOS JIT limitations - instead they are evaluated.
Sadly the evaluation of operators like == turned out to be quite difficult to do without using dynamic code...
Because of this, what the Tibet == operator tries to do is to reduce the right and left sides down to one of three types: long, double or object - it does this using:
private Type GetLookupTypeFor(object value)
{
if (value == null)
return null;
if (value is long)
return typeof(long);
if (value is double)
return typeof (double);
return typeof (object);
}
from https://github.com/MvvmCross/MvvmCross/blob/v3.1/Cirrious/Cirrious.MvvmCross.Binding/Combiners/MvxPairwiseValueCombiner.cs#L36
with these types determined it then calls one of these methods, each of which uses the == operator of the left-hand type or .Equals if both types are object:
protected override bool CombineDoubleAndDouble(double input1, double input2, out object value)
{
value = input1 == input2;
return true;
}
protected override bool CombineDoubleAndLong(double input1, long input2, out object value)
{
value = input1 == input2;
return true;
}
// ... etc
from https://github.com/MvvmCross/MvvmCross/blob/v3.1/Cirrious/Cirrious.MvvmCross.Binding/Combiners/VeryExperimental/MvxEqualToValueCombiner.cs
For the enum case of State==1, I think the left-hand will be identified as an object and the right-hand as a long - so these will never be equal because of:
protected override bool CombineObjectAndLong(object input1, long input2, out object value)
{
value = false;
return true;
}
Working with the current code, I think the only way to get the test to work is to get both left and right-side to long or to string.
You could do that using a value converter on the enum - e.g. a ToStringValueConverter or a ToLongValueConverter which you could then use like:
If(ToLong(State)==1, 'Visible', 'Gone'
or:
If(ToString(State)=='Running', 'Visible', 'Gone'
Obviously, looking forwards, this area could also be improved inside Mvx - in whatever lies beyond Swiss and Tibet
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With