【问题标题】:Change entry Border color using Custom Renderers in xamarin在 xamarin 中使用自定义渲染器更改条目边框颜色
【发布时间】:2020-10-19 15:38:46
【问题描述】:

I have used custom renderer class and i am able to change the border color. Now on click of a button i want to reset it again。我尝试通过单击按钮重置它,但它不适用于 iOS 和 Android。

       .xaml file

       <local:BorderedEntryRenderer x:Name="NameEntry"
                     HorizontalOptions="EndAndExpand" VerticalOptions="Start"
                     WidthRequest="210"
                     Text="{Binding ProfileName}" BorderColor="Chocolate" />


       .cs file

         public void EditProfile_Clicked(System.Object sender, System.EventArgs e)
         {
            NameEntry.BorderColor = Color.Blue; //to reset the color on click
         }

【问题讨论】:

    标签: xamarin.forms custom-renderer


    【解决方案1】:

    欢迎来到 SO!

    如果想在 Xamarin Forms 中为 Entry 使用自定义渲染器,可以先看看这个文档 (https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/custom-renderer/entry)

    这里如果需要改变Entry的边框颜色,其实需要使用自定义渲染器来实现。

    在表单中创建自定义Entry

    public class MyEntry : Entry
    {
    }
    

    Xaml 中使用:

    <ContentPage ...
        xmlns:local="clr-namespace:CustomRenderer;assembly=CustomRenderer"
        ...>
        ...
        <local:MyEntry Text="In Shared Code" />
        ...
    </ContentPage>
    

    那么在iOS解决方案中,需要创建一个渲染器类(如CustomEntryRenderer):

    [assembly: ExportRenderer(typeof(MyEntry), typeof(CustomEntryRenderer))]
    namespace AppEntryTest.iOS
    {
        public class CustomEntryRenderer : EntryRenderer,IUITextFieldDelegate
        {
            protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
            {
                base.OnElementChanged(e);
    
                Control.Layer.BorderColor = UIColor.Red.CGColor;
                Control.Layer.BorderWidth = 1;
            }
    
        }
    }
    

    同样在Android解决方案中,需要创建一个自定义的渲染器类:

    [assembly: ExportRenderer(typeof(MyEntry), typeof(CustomEntryRenderer))]
    namespace AppEntryTest.Android{
    public class CustomEntryRenderer : EntryRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
        {
            base.OnElementChanged(e);
            if (e.OldElement == null)
            {
                var nativeEditText = (global::Android.Widget.EditText)Control;
                var shape = new ShapeDrawable(new Android.Graphics.Drawables.Shapes.RectShape());
                shape.Paint.Color = Xamarin.Forms.Color.Red.ToAndroid();
                shape.Paint.SetStyle(Paint.Style.Stroke);
                nativeEditText.Background = shape;
            }
        }
    }
    

    效果:

    ==============================更新================= ===============

    如果想用事件来控制Entry的边框,我们可以使用MessageCenter来实现。

    例如,我们可以在Xaml中创建两个按钮,添加两个点击方法来控制Entry的边框。

    <Button Text="SetBorder" Clicked="Button_Clicked_setborder"/>
    <Button Text="Reset" Clicked="Button_Clicked_reset"/>
    

    每个点击方法的实现是:

    private void Button_Clicked_setborder(object sender, EventArgs e)
    {
        MessagingCenter.Send<object,bool>(this,"Hi",true);
    }
    
    private void Button_Clicked_reset(object sender, EventArgs e)
    {
        MessagingCenter.Send<object, bool>(this, "Hi", false);
    }
    

    然后在iOS入口渲染器类中,修改如下:

    [assembly: ExportRenderer(typeof(MyEntry), typeof(CustomEntryRenderer))]
    namespace AppEntryTest.iOS
    {
        public class CustomEntryRenderer : EntryRenderer,IUITextFieldDelegate
        {
    
            CoreGraphics.CGColor defaultBorderColor;
            nfloat defaultBorderWidth;
    
            protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
            {
                base.OnElementChanged(e);
    
                defaultBorderColor = Control.Layer.BorderColor;
                defaultBorderWidth = Control.Layer.BorderWidth;
    
    
                MessagingCenter.Subscribe<object, bool>(this, "Hi", (sender, arg) =>
                {
                    // Do something whenever the "Hi" message is received
                    Console.WriteLine("Hi , I have received this");
                    if (arg)
                    {
                        Control.Layer.BorderColor = UIColor.Red.CGColor;
                        Control.Layer.BorderWidth = 1;
                    }
                    else
                    {
                        Control.Layer.BorderColor = defaultBorderColor;
                        Control.Layer.BorderWidth = defaultBorderWidth;
                    }
    
                });
    
              
            }
    
        }
    }
    

    Android渲染器类中同样修改:

    [assembly: ExportRenderer(typeof(MyEntry), typeof(CustomEntryRenderer))]
    namespace AppEntryTest.Droid
    {
        [Obsolete]
        public class CustomEntryRenderer : EntryRenderer
        {
            Drawable defaultTextBackgroundColor;
            public CustomEntryRenderer(Context context) : base(context)
            {
            }
    
            protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
            {
                base.OnElementChanged(e);
                
                defaultTextBackgroundColor = Control.Background;
    
                MessagingCenter.Subscribe<object,bool>(this, "Hi", (sender,arg) =>
                {
                    // Do something whenever the "Hi" message is received
                    Console.WriteLine("Hi , I have received this");
                    if (arg)
                    {
                        var shape = new ShapeDrawable(new Android.Graphics.Drawables.Shapes.RectShape());
                        shape.Paint.Color = Xamarin.Forms.Color.Red.ToAndroid();
                        shape.Paint.SetStyle(Paint.Style.Stroke);
                        Control.Background = shape;
                    }
                    else
                    {
                        Control.Background = defaultTextBackgroundColor;
                    }
               
                });
    
            }
    
        }
    }
    

    效果:

    【讨论】:

    • 我已经使用了所有这些东西,并且在自定义渲染器的帮助下,我能够更改条目的边框颜色,现在我想通过单击我无法重新设置的按钮再次重置它做
    • @SaumyaSaloni Okey,我猜你可能希望Entry focused 显示边框,unfocused 显示默认样式。如果是这样,我会更新答案。
    • 这个想法是一旦用户导航到这个屏幕,条目的边框颜色应该是褪色的颜色,并且在同一个屏幕中我们有编辑配置文件图标,一旦用户选择该图标,条目的边框颜色应该改变到明亮的东西。是否有可能 - (与关注条目无关) - 单击图像按钮时颜色应该改变。
    • @SaumyaSaloni Okey,明白了。我将在 Xamarin Forms 中检查是否可行。
    • @SaumyaSaloni 我们可以使用 MessageCenter 来实现,我会更新答案。
    【解决方案2】:

    我认为你应该结帐Xamarin Forms Triggers

    使用触发器,您将能够从动作或状态触发事件。 它还可以帮助您将所有内容组织在 xaml 文件中,而无需背后的代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-09-03
      • 1970-01-01
      • 2021-05-01
      • 2021-10-05
      • 2013-01-06
      • 2019-02-16
      • 1970-01-01
      相关资源
      最近更新 更多