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
相关产品推荐
相关产品推荐

