为什么我的BoxView上的边框是圆的?

时间:2016-08-31 15:45:49

标签: xaml xamarin.forms

我正在尝试在Xamarin.Forms的XAML页面中创建一个s eparator之间的StackLayouts ,我可以使用BoxView轻松完成。

但是当我尝试向BoxView添加边框时(通过添加一个框架)我无法在最后找到 not curve

enter image description here

我已经尝试过各种方法让这项工作毫无运气。我甚至尝试将BoxView 伸出屏幕(看一下后一张图片)让曲线离开屏幕(此刻就会好起来甚至

这是只有少数我尝试过的东西没有任何运气。

<!--Test 1. -->
      <Frame OutlineColor="{DynamicResource CardOutlineColor}" HasShadow="False" Padding="0" VerticalOptions="FillAndExpand">
        <BoxView x:Name="boxViewSeparator" HeightRequest="15" WidthRequest="10000" BackgroundColor="{DynamicResource WindowsBackgroundColor}" />
      </Frame>

 <!--Test 2. -->
      <AbsoluteLayout VerticalOptions="FillAndExpand"
      HorizontalOptions="FillAndExpand">
        <Frame OutlineColor="{DynamicResource CardOutlineColor}" HasShadow="False" Padding="0" VerticalOptions="FillAndExpand">

          <BoxView AbsoluteLayout.LayoutBounds="1.0, 1.0, 1.0, 1.0"
                      Color="#f2f3f3"
                      AbsoluteLayout.LayoutFlags="All" BackgroundColor="{DynamicResource WindowsBackgroundColor}" />
        </Frame>
      </AbsoluteLayout>

 <!--Test3. -->
      <Frame OutlineColor="{DynamicResource CardOutlineColor}" HasShadow="False" Padding="0" VerticalOptions="FillAndExpand">
        <ContentView HeightRequest="15" BackgroundColor="{DynamicResource WindowsBackgroundColor}" />
      </Frame>

 <!--Test 4. -->
      <Frame OutlineColor="{DynamicResource CardOutlineColor}" HasShadow="False" Padding="0" VerticalOptions="FillAndExpand">
        <ContentView HeightRequest="15" BackgroundColor="{DynamicResource WindowsBackgroundColor}" MinimumWidthRequest="500"/>
      </Frame>

我最接近这个代码

<AbsoluteLayout VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
        <Frame OutlineColor="{DynamicResource CardOutlineColor}" HasShadow="False"
               Padding="0" VerticalOptions="FillAndExpand"
              AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="1.5, 1.5, 1.2, 1.0">
          <BoxView  HeightRequest="15" BackgroundColor="{DynamicResource WindowsBackgroundColor}" />
        </Frame>
      </AbsoluteLayout>

但是结果是我只能将ViewBox的其他部分移出窗口

有没有人有其他想法?

enter image description here

2 个答案:

答案 0 :(得分:0)

好的,我发现了如何做到这一点,就像你知道的一切一样,很简单: - )

只需在StackLayout 中使用 3个BoxView,而不使用填充/间距。

    <StackLayout Orientation ="Vertical" Padding="0" Spacing="0">
      <BoxView BackgroundColor="#d6dbdb" HeightRequest="1" VerticalOptions="End" HorizontalOptions="FillAndExpand"/>
      <BoxView HeightRequest="15" BackgroundColor="#f2f3f3"/>
      <BoxView BackgroundColor="#d6dbdb" HeightRequest="1" VerticalOptions="End" HorizontalOptions="FillAndExpand"/>
    </StackLayout>

结果如下。 enter image description here

P.S 我想看看如何将画面设置在屏幕外...

答案 1 :(得分:0)

我找到了更优雅的解决方案(恕我直言):

创建自定义框视图:

public class Border : BoxView
{
    public static readonly BindableProperty BorderColorProperty =
        BindableProperty.Create(nameof(BorderColor),
                                typeof(Color),
                                typeof(Border),
                                Color.Transparent);

    public static readonly BindableProperty BorderWidthProperty =
        BindableProperty.Create(nameof(BorderWidth),
                                typeof(double),
                                typeof(Border),
                                0d);

    public Color BorderColor
    {
        get { return (Color)GetValue(BorderColorProperty); }
        set { SetValue(BorderColorProperty, value); }
    }

    public double BorderWidth
    {
        get { return (double)GetValue(BorderWidthProperty); }
        set { SetValue(BorderWidthProperty, value); }
    }
}

实施渲染器:

<强>机器人

public class BorderRenderer : VisualElementRenderer<BoxView>
{
    public BorderRenderer()
    {

    }

    protected override void OnElementChanged(ElementChangedEventArgs<BoxView> e)
    {
        base.OnElementChanged(e);

        SetWillNotDraw(false);

        Invalidate();
    }

    public override void Draw(Canvas canvas)
    {
        var border = Element as Border;

        base.Draw(canvas);

        var paint = new Paint();
        paint.StrokeWidth = (float)border.BorderWidth;
        paint.SetStyle(Paint.Style.Stroke);
        paint.SetARGB(ConvertTo255ScaleColor(border.BorderColor.A), ConvertTo255ScaleColor(border.BorderColor.R), ConvertTo255ScaleColor(border.BorderColor.G), ConvertTo255ScaleColor(border.BorderColor.B));

        SetLayerType(Android.Views.LayerType.Software, paint);

        var number = (float)border.BorderWidth / 2;
        var rectF = new RectF(
                    number, // left
                    number, // top
                    canvas.Width - number, // right
                    canvas.Height - number // bottom
            );


        canvas.DrawRoundRect(rectF, 0, 0, paint);
    }

    private int ConvertTo255ScaleColor(double color)
    {
        return (int)Math.Ceiling(color * 255);
    }
}

<强>的iOS

public class BorderRenderer : VisualElementRenderer<BoxView>
{
    public BorderRenderer()
    {

    }

    protected override void OnElementChanged(ElementChangedEventArgs<BoxView> e)
    {
        base.OnElementChanged(e);

        if (Element == null)
            return;

        Layer.MasksToBounds = true;
        Layer.CornerRadius = 0f;
    }

    public override void Draw(CGRect rect)
    {
        var border = (Border)Element;
        using (var context = UIGraphics.GetCurrentContext())
        {
            context.SetFillColor(border.Color.ToCGColor());
            context.SetStrokeColor(border.BorderColor.ToCGColor());
            context.SetLineWidth((float)border.BorderWidth);

            var rCorner = Bounds.Inset((int)border.BorderWidth / 2, (int)border.BorderWidth / 2);

            var radius = (nfloat)border.CornerRadius;
            radius = (nfloat)Math.Max(0, Math.Min(radius, Math.Max(rCorner.Height / 2, rCorner.Width / 2)));

            var path = CGPath.FromRoundedRect(rCorner, radius, radius);
            context.AddPath(path);
            context.DrawPath(CGPathDrawingMode.FillStroke);
        }
    }
}

不要忘记在每个渲染器上添加namespace以上的属性:

[assembly: ExportRenderer(typeof(Border), typeof(BorderRenderer))]