C# 表单动态按钮样式

C# 表单动态按钮样式,c#,android,xamarin,android-styles,C#,Android,Xamarin,Android Styles,我想实现我自己的自定义按钮样式。每当按钮改变其状态时(从启用变为禁用,即),样式必须改变 我目前的解决方案是在Android中定义一种样式,我的自定义按钮浏览器将此样式应用于按钮 按钮样式.xml: <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true" > <shape> <s

我想实现我自己的自定义按钮样式。每当按钮改变其状态时(从启用变为禁用,即),样式必须改变

我目前的解决方案是在Android中定义一种样式,我的自定义按钮浏览器将此样式应用于按钮

按钮样式.xml:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:state_pressed="true" >
    <shape>
      <solid
          android:color="#d7d7d7" />
      <stroke
          android:width="1dp"
          android:color="#d7d7d7" />
      <corners
          android:radius="6dp" />
      <padding
          android:left="10dp"
          android:top="10dp"
          android:right="10dp"
          android:bottom="10dp" />
    </shape>
  </item>
  <item android:state_enabled="false">
    <shape>
      <solid
          android:color="#efefef" />
      <stroke
          android:width="1dp"
          android:color="#efefef" />
      <corners
          android:radius="6dp" />
      <padding
          android:left="10dp"
          android:top="10dp"
          android:right="10dp"
          android:bottom="10dp" />
    </shape>
  </item>
  <item>
    <shape>
      <gradient
          android:startColor="#d7d7d7"
          android:endColor="#d7d7d7"
          android:angle="270" />
      <stroke
          android:width="1dp"
          android:color="#d7d7d7" />
      <corners
          android:radius="6dp" />
      <padding
          android:left="10dp"
          android:top="10dp"
          android:right="10dp"
          android:bottom="10dp" />
    </shape>
  </item>
</selector>
using FrameworkForms.UserControl;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using Color = Android.Graphics.Color;

[assembly: ExportRenderer(typeof(CustomButton), typeof(FrameworkForms.Droid.Renderer.CustomizedButtonRenderer))]
namespace FrameworkForms.Droid.Renderer
{
    public class CustomizedButtonRenderer : ButtonRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
        {
            base.OnElementChanged(e);
            if (Control != null)
            {
                Control.SetBackgroundResource(Resource.Drawable.button_style);
                Control.SetAllCaps(false);
                if (!Control.Enabled)
                {
                    Control.SetTextColor(Color.ParseColor("#858585"));
                }
            }
        }
    }
}

自定义渲染器:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:state_pressed="true" >
    <shape>
      <solid
          android:color="#d7d7d7" />
      <stroke
          android:width="1dp"
          android:color="#d7d7d7" />
      <corners
          android:radius="6dp" />
      <padding
          android:left="10dp"
          android:top="10dp"
          android:right="10dp"
          android:bottom="10dp" />
    </shape>
  </item>
  <item android:state_enabled="false">
    <shape>
      <solid
          android:color="#efefef" />
      <stroke
          android:width="1dp"
          android:color="#efefef" />
      <corners
          android:radius="6dp" />
      <padding
          android:left="10dp"
          android:top="10dp"
          android:right="10dp"
          android:bottom="10dp" />
    </shape>
  </item>
  <item>
    <shape>
      <gradient
          android:startColor="#d7d7d7"
          android:endColor="#d7d7d7"
          android:angle="270" />
      <stroke
          android:width="1dp"
          android:color="#d7d7d7" />
      <corners
          android:radius="6dp" />
      <padding
          android:left="10dp"
          android:top="10dp"
          android:right="10dp"
          android:bottom="10dp" />
    </shape>
  </item>
</selector>
using FrameworkForms.UserControl;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using Color = Android.Graphics.Color;

[assembly: ExportRenderer(typeof(CustomButton), typeof(FrameworkForms.Droid.Renderer.CustomizedButtonRenderer))]
namespace FrameworkForms.Droid.Renderer
{
    public class CustomizedButtonRenderer : ButtonRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
        {
            base.OnElementChanged(e);
            if (Control != null)
            {
                Control.SetBackgroundResource(Resource.Drawable.button_style);
                Control.SetAllCaps(false);
                if (!Control.Enabled)
                {
                    Control.SetTextColor(Color.ParseColor("#858585"));
                }
            }
        }
    }
}
使用FrameworkForms.UserControl;
使用Xamarin.Forms;
使用Xamarin.Forms.Platform.Android;
使用Color=Android.Graphics.Color;
[程序集:ExportRenderer(typeof(CustomButton)、typeof(FrameworkForms.Droid.Renderer.CustomizedButtonRenderer))]
命名空间FrameworkForms.Droid.Renderer
{
公共类CustomizedButtonRenderer:ButtonRenderer
{
受保护的覆盖无效OnElementChanged(ElementChangedEventArgs e)
{
基础。一个要素发生变化(e);
if(控件!=null)
{
控件.SetBackgroundResource(Resource.Drawable.button_样式);
控制。设置所有上限(假);
如果(!Control.Enabled)
{
Control.SetTextColor(Color.ParseColor(#858585”);
}
}
}
}
}
“我的按钮已启用”属性上存在绑定。问题很明显,一旦属性更改,按钮就不会再次渲染,并保持以前状态的textcolor

我对Xamarin.Forms中的样式做了一些研究。看起来动态样式应该适合我,但我希望我所有的按钮都能使用它(像一个全局样式)。我能把它们结合起来吗?或者这是更好的解决方案?值得一提的是,我不介意再次为iOS实现整个过程。无论如何都会不一样的。所以Android xml样式也可以做到这一点


谢谢。

如果您想在启用
属性时更改某些内容,则需要重写
OneElementPropertyChanged

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);
        if(e.PropertyName == "IsEnabled")
        {
            if(Element.IsEnabled)
            {
                Control.SetTextColor(Color.ParseColor("#858585"));
                Control.SetBackgroundResource(Resource.Drawable.YourEnabledResource);
            }
            else
            {
                Control.SetTextColor(Element.TextColor.ToAndroid());
                Control.SetBackgroundResource(Resource.Drawable.YourDisabledResource);
            }
        }
    }

然后,您可以创建两个可绘制的xml文件来定义启用和禁用的不同资源。我相应地给它们命名为
YourEnabledResource
YourDisabledResource

这不是问题所在。绑定工作正常,按钮的背景已设置。这是您的问题。我以
SetTextColor
为例。这一点仍然是一样的。更改
IsEnabled
属性时,它会在此处激发,如果您需要更改背景资源,也可以在此处激发。我将编辑我的答案以使其更清晰……而且,答案直接回应了这一点:“问题很明显,一旦属性更改,按钮就不会再次渲染,并保持前一状态的文本颜色。”。。。。这将在您更改
IsEnabled
属性时更改文本颜色。这就是重点。更清楚的是,您应该以现在的方式覆盖
OnElementChanged
,但也要覆盖
OnElementPropertyChanged
。每当您更改Xamarin.Forms元素上任何可绑定属性的值时,此方法都将触发。对不起,我没有真正阅读您的答案。当然了,谢谢:-)