You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin应用中如何给按钮仅添加左右两侧边框?

Xamarin按钮仅显示左右边框的几种实现方法

默认Xamarin.Forms的Button控件设置BorderWidth后会给四边加上边框,要实现只显示左右边框,不止自定义渲染器一种方案,下面是几种实用的实现方式:

一、自定义渲染器(原生级方案,适配性最好)

这种方式直接针对Android和iOS平台的原生控件做修改,效果最贴合原生体验。

步骤1:创建自定义Button控件

在共享项目里定义一个继承自Button的自定义控件:

public class CustomBorderButton : Button
{
    // 可按需添加自定义属性,比如单独的左右边框宽度、颜色,这里先沿用原Button的BorderWidth和BorderColor
}

步骤2:编写Android平台渲染器

在Android项目中添加渲染器:

[assembly: ExportRenderer(typeof(CustomBorderButton), typeof(CustomBorderButtonRenderer))]
namespace YourAppName.Droid.Renderers
{
    public class CustomBorderButtonRenderer : ButtonRenderer
    {
        public CustomBorderButtonRenderer(Context context) : base(context) { }

        protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
        {
            base.OnElementChanged(e);
            if (Control == null) return;

            // 替换背景为自定义Drawable,仅绘制左右边框
            Control.Background = new LeftRightBorderDrawable(
                Element.BorderColor.ToAndroid(), 
                (float)TypedValue.ApplyDimension(ComplexUnitType.Dip, Element.BorderWidth, Context.Resources.DisplayMetrics)
            );
            Control.SetBackgroundColor(Element.BackgroundColor.ToAndroid());
        }

        // 自定义Drawable,仅绘制左右边框
        private class LeftRightBorderDrawable : Drawable
        {
            private readonly Paint _borderPaint;
            private readonly float _borderWidth;

            public LeftRightBorderDrawable(Color borderColor, float borderWidth)
            {
                _borderPaint = new Paint();
                _borderPaint.Color = borderColor;
                _borderPaint.StrokeWidth = borderWidth;
                _borderPaint.SetStyle(Paint.Style.Stroke);
                _borderWidth = borderWidth;
            }

            public override void Draw(Canvas canvas)
            {
                // 绘制左边框(居中对齐)
                canvas.DrawLine(_borderWidth / 2, 0, _borderWidth / 2, canvas.Height, _borderPaint);
                // 绘制右边框(居中对齐)
                canvas.DrawLine(canvas.Width - _borderWidth / 2, 0, canvas.Width - _borderWidth / 2, canvas.Height, _borderPaint);
            }

            public override void SetAlpha(int alpha) => _borderPaint.Alpha = alpha;
            public override void SetColorFilter(ColorFilter colorFilter) => _borderPaint.SetColorFilter(colorFilter);
            public override int Opacity => PixelFormat.Translucent;
        }
    }
}

步骤3:编写iOS平台渲染器

在iOS项目中添加渲染器:

[assembly: ExportRenderer(typeof(CustomBorderButton), typeof(CustomBorderButtonRenderer))]
namespace YourAppName.iOS.Renderers
{
    public class CustomBorderButtonRenderer : ButtonRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
        {
            base.OnElementChanged(e);
            if (Control == null) return;

            // 清空默认边框
            Control.Layer.BorderWidth = 0;
            Control.BackgroundColor = Element.BackgroundColor.ToUIColor();
            // 添加左右边框层
            UpdateBorderLayers();
        }

        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);
            // 按钮尺寸变化时更新边框位置
            if (e.PropertyName == VisualElement.WidthProperty.PropertyName || 
                e.PropertyName == VisualElement.HeightProperty.PropertyName)
            {
                UpdateBorderLayers();
            }
        }

        private void UpdateBorderLayers()
        {
            // 移除旧的边框层
            foreach (var layer in Control.Layer.Sublayers?.Where(l => l.Name is "LeftBorder" or "RightBorder").ToList() ?? new List<CALayer>())
            {
                layer.RemoveFromSuperLayer();
            }

            var borderWidth = (nfloat)Element.BorderWidth;
            var borderColor = Element.BorderColor.ToCGColor();

            // 添加左边框
            var leftBorder = new CALayer { Name = "LeftBorder" };
            leftBorder.Frame = new CGRect(0, 0, borderWidth, Control.Frame.Height);
            leftBorder.BackgroundColor = borderColor;
            Control.Layer.AddSublayer(leftBorder);

            // 添加右边框
            var rightBorder = new CALayer { Name = "RightBorder" };
            rightBorder.Frame = new CGRect(Control.Frame.Width - borderWidth, 0, borderWidth, Control.Frame.Height);
            rightBorder.BackgroundColor = borderColor;
            Control.Layer.AddSublayer(rightBorder);
        }
    }
}

步骤4:在XAML中使用

引入自定义控件命名空间后直接使用:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:YourAppName"
             x:Class="YourAppName.MainPage">

    <local:CustomBorderButton
        BackgroundColor="{StaticResource MyBackgroundColor}"
        BorderColor="{StaticResource PrimaryColor}"
        BorderWidth="0.1"
        Text="仅左右边框按钮" />

</ContentPage>

二、布局包裹法(零代码,快速实现)

不需要编写C#代码,用ContentView嵌套按钮模拟边框:

<ContentView
    BackgroundColor="{StaticResource PrimaryColor}"
    Padding="0.1, 0, 0.1, 0" <!-- 左右padding值即为边框宽度 -->
    HorizontalOptions="Fill"
    VerticalOptions="Center">
    
    <Button
        BackgroundColor="{StaticResource MyBackgroundColor}"
        BorderWidth="0" <!-- 必须去掉按钮自身边框 -->
        Text="模拟左右边框按钮" />
        
</ContentView>

如果按钮需要圆角,给ContentView设置和按钮相同的CornerRadius,并将ClipToBounds设为True即可。

三、Shape绘制法(灵活布局场景)

用Xamarin.Forms的Rectangle控件给按钮添加左右边框,适合需要动态调整边框位置的场景:

<RelativeLayout HorizontalOptions="Fill" VerticalOptions="Center">
    <Button
        x:Name="TargetButton"
        BackgroundColor="{StaticResource MyBackgroundColor}"
        BorderWidth="0"
        Text="Shape绘制边框按钮"
        HorizontalOptions="Fill" />
        
    <!-- 左边框 -->
    <Rectangle
        Fill="{StaticResource PrimaryColor}"
        WidthRequest="0.1"
        RelativeLayout.XConstraint="{ConstraintExpression Type=Constant, Constant=0}"
        RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToView, ElementName=TargetButton, Property=Y}"
        RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToView, ElementName=TargetButton, Property=Height}" />
        
    <!-- 右边框 -->
    <Rectangle
        Fill="{StaticResource PrimaryColor}"
        WidthRequest="0.1"
        RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToView, ElementName=TargetButton, Property=Width, Constant=-0.1}"
        RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToView, ElementName=TargetButton, Property=Y}"
        RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToView, ElementName=TargetButton, Property=Height}" />
</RelativeLayout>

内容的提问来源于stack exchange,提问作者Rashedul.Rubel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 04:45:33