首页 > 解决方案 > 按钮颜色绑定影响大小

问题描述

我有三个按钮。如果元素可以更改,则保存按钮的颜色为绿色,如果无法更改,则为灰色。我将按钮的颜色与 ViewModel 上的属性绑定,该属性是一个字符串,并使用 Converter 转换字符串的值。当我从按钮上移除颜色的绑定时,尺寸很好,但是通过绑定,尺寸小于其他按钮的尺寸。

<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>

我的转换器:

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;
    }
}

我的视图模型:

public string PropertyButtonColor 
    { 
        get
        {
            if (CanSave())                
                return "Green";                
            else
                return "Gray";
        } 
    }

关于它为什么会发生的任何想法?

标签: c#.netxamlxamarinxamarin.forms

解决方案


这个问题不是由绑定引起的,如果你为 设置了 backgroundColor Button,这个 Buttons 的大小将在 android 中改变,如下面的截图。

在此处输入图像描述

实际上这是一个不同的drawable正在使用

因为您要求纯色,请注意wczytajOstatniButtonwczytajWzorzecButton有阴影

saveButton没有它,它是蓝色的。

如果您Show Layout Bounds在开发人员选项中启用,您将看到控件的实际边界,并且可能很清楚按钮是否变大,或者只是不同的可绘制对象使其看起来

在此处输入图像描述

这是解决此问题的解决方法,您可以创建自定义按钮。

 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);
            }
        }
    }

然后在android中创建一个自定义渲染器。SetColorFilter在控制背景上设置

[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);
                }
            }
        }
    }
}

这是运行截图。

在此处输入图像描述

在此处输入图像描述


推荐阅读