Issue
I have three buttons. The save button's color is Green if the element can be changed and Gray if it cannot be changed. I bind the color of the button with property on ViewModel which is a string and Convert the value of the string using Converter. When I remove the binding of the color from the button, the size is fine, but with the binding, the size is smaller than other buttons' size.
<StackLayout Grid.Row="3"
Orientation="Horizontal"
Padding="5,5,5,5"
BackgroundColor="CadetBlue">
<Button x:Name="wczytajWzorzecButton"
WidthRequest="120" HeightRequest="20"
Text="Last" FontSize="12"
HorizontalOptions="CenterAndExpand"
Command="{Binding GetTemplateCommand}"/>
<Button x:Name="wczytajOstatniButton"
WidthRequest="120" HeightRequest="20"
Text="First" FontSize="12"
HorizontalOptions="EndAndExpand"
Command="{Binding GetLastDocumentCommand}"/>
<Button x:Name="saveButton"
WidthRequest="120" HeightRequest="20"
Text="Save" FontSize="12"
BackgroundColor="{Binding PropertyButtonColor, Converter={StaticResource StringToColorConverter}}"
HorizontalOptions="StartAndExpand"
Command="{Binding SaveDocumentCommand}"/>
</StackLayout>
My converter:
public class StringToColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string valueAsString = value.ToString();
switch (valueAsString)
{
case ("White"):
{
return Color.White;
}
case ("Gray"):
{
return Color.DarkGray;
}
case ("LighGreen"):
{
return Color.LightGreen;
}
default:
{
return Color.FromHex(value.ToString());
}
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return null;
}
}
My ViewModel:
public string PropertyButtonColor
{
get
{
if (CanSave())
return "Green";
else
return "Gray";
}
}
Any ideas on why it might be happening?
Solution
This issue is not caused by binding, If you set the backgroundColor for Button
, this Buttons size will be changed in android like following screenshot.
Actually that is a different drawable is being used
because you've requested a solid color, note that the wczytajOstatniButton
and wczytajWzorzecButton
have a shadow
But saveButton
does not have it, it is blue.
if you enable Show Layout Bounds
in Developer Options you will see the actual boundaries of the controls and it might be clear whether the button is getting larger, or just that the different drawable makes it appear to
Here is an workaround to fix this issue, you can create an custon Button.
public class TintableButton : Button
{
public static readonly BindableProperty TintColorProperty = BindableProperty.Create("TintColor", typeof(Color), typeof(Button), (object)Color.Default, BindingMode.OneWay, (BindableProperty.ValidateValueDelegate)null, (BindableProperty.BindingPropertyChangedDelegate)null, (BindableProperty.BindingPropertyChangingDelegate)null, (BindableProperty.CoerceValueDelegate)null, (BindableProperty.CreateDefaultValueDelegate)null);
public Color TintColor
{
get
{
return (Color)GetValue(TintColorProperty);
}
set
{
SetValue(TintColorProperty, value);
}
}
}
Then create an custom renderer in android. set SetColorFilter
on the Control Background
[assembly: ExportRenderer(typeof(TintableButton), typeof(TintableButtonRenderer))]
namespace ImageViewModel.Droid
{
public class TintableButtonRenderer : ButtonRenderer
{
public TintableButtonRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Button> e)
{
base.OnElementChanged(e);
var control = e.NewElement as TintableButton;
if (control != null)
{
if (control.TintColor != Xamarin.Forms.Color.Default)
{
var androidColor = control.TintColor.ToAndroid();
Control.Background.SetColorFilter(androidColor, PorterDuff.Mode.Src);
}
}
}
}
}
Here is running screenshot.
Answered By - Leon Lu - MSFT
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.