I am working on Xamarin form apps. I wanted to to set Grdiview backgroud color based on condition of properties.
I know I can create a new property in class file and then bind to xaml but is there way to use ternary condition in Xaml itself.
my code is
<Grid Margin="5,0,5,5" Padding="10" BackgroundColor="White">
This Grid being bind to model , which is having property IsRead ( null-able Boolean). Now I want to put condition that when IsRead is true then set Background color to Grey, otherwise White.
How can I do that within xaml?
I've never heard about such a thing, but you can use a converter instead. It's your best choice. It's clean, reusable and easy programmable.
Here is a well elaborated solution to this kind of need (surely you can do it in lots of ways, this one is just one).
Create a struct to make the solution completely reusable:
public struct NullableBoolColorScheme
{
public Color TrueColor { get; set; }
public Color FalseColor { get; set; }
public Color NullColor { get; set; }
public NullableBoolColorScheme(Color trueColor, Color falseColor, Color nullColor)
{
TrueColor = trueColor;
FalseColor = falseColor;
NullColor = nullColor;
}
public Color GetColor(bool? value)
{
if (!value.HasValue)
return NullColor;
else
return value.Value ? TrueColor : FalseColor;
}
}
Create your converter:
public class NullableBoolToColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (!(value is bool?)) return null;
Color returningColor = Color.Default;
if (parameter != null && parameter is NullableBoolColorScheme)
returningColor = ((NullableBoolColorScheme)parameter).GetColor((value as bool?));
return returningColor;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new Exception("Conversion not allowed");
}
}
Handle it in your ViewModel:
public class MyViewModel // Remember to implement INotifyPropertyChanged and raise property changes
{
public bool? MyNullableBoolProperty
{
get;
set;
}
public NullableBoolColorScheme AppColorScheme { get; }
public MyViewModel()
{
AppColorScheme = new NullableBoolColorScheme(Color.Gray, Color.White, Color.Transparent /* Some possibilities are open here =) */);
}
}
Use it in XAML:
<!-- Declare your namespace -->
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:converter="clr-namespace:Namespace.Converters"
...
>
<!-- Create your resources dictionary and add a converter instance -->
<ContentPage.Resources>
<ResourceDictionary>
<converter:NullableBoolToColorConverter x:Key="NullableBoolToColorConverter" />
</ResourceDictionary>
</ContentPage.Resources>
<!-- Have fun -->
<Grid Margin="5,0,5,5"
Padding="10"
BackgroundColor="{Binding MyNullableBoolProperty, Mode=OneWay, Converter={StaticResource NullableBoolToColorConverter}, ConverteParameter={Binding AppColorScheme}}">
...
</Grid>
...
</ContentPage>
I hope it help you.
You can not use Ternary in XAML.
Solution 1 (Using Converter):
You can probably go with using ValueConverter
. Create a Converter which implements IValueConverter
.
public class ReadUnReadToColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
bool? isRead = Convert.ToBoolean(value);
if(isRead.HasValue && isRead.Value == true)
{
return Color.Grey;
}
return Color.White;
}
//You may not need the Convert Back method. This will need to convert Color back to Boolean
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
In your XAML Resource, add this class as a static resource, then you can use this converter to bind value and convert based on this.
<ContentPage.Resources>
<local:ReadUnReadToColorConverter x:Key="ReadUnReadToColorConverter" />
</ContentPage.Resources>
Now, Bind this Converter to your Grid as follows:
<Grid Margin="5,0,5,5" Padding="10" BackgroundColor="{Binding IsRead, Converter={StaticResource ReadUnReadToColorConverter}}">
Solution 2 (Using Property Binding (OneWay solution only)):
You can simply have a Color
Property in your ViewModel
and return value in the get
method of the property based on the condition as follows:
public Color ReadUnReadBackgroundColor
{
get
{
if(IsRead.HasValue && IsRead.Value == true)
{
return Color.Grey;
}
return Color.White;
}
}
Now Bind this with Grid's BackgroundColor
Property:
<Grid Margin="5,0,5,5" Padding="10" BackgroundColor="{Binding ReadUnReadBackgroundColor}">
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