xamarin / Xamarin.Forms

Xamarin.Forms is no longer supported. Migrate your apps to .NET MAUI.
https://aka.ms/xamarin-upgrade
Other
5.62k stars 1.87k forks source link

[UWP] SetNativeControl 'Value does not fall within the expected range' #4756

Open Ali-YousefiTelori opened 5 years ago

Ali-YousefiTelori commented 5 years ago

Hi, When I want to SetNativeControl in uwp renderer i get error 'Value does not fall within the expected range' I don't know what is wrong here.

this is a border with thickness radius and after i custom my native border in renderer i want to set child of xamarin contentview renderer to my native border renderer

Example:

portable class:

using Xamarin.Forms;

namespace AsNum.XFControls {

    /// <summary>
    /// 边框
    /// </summary>
    public class Border : ContentView {

        /// <summary>
        /// 圆角大小
        /// </summary>
        public static readonly BindableProperty CornerRadiusProperty =
            BindableProperty.Create("CornerRadius",
                typeof(CornerRadius),
                typeof(Border),
                default(CornerRadius)
                );

        /// <summary>
        /// 边框颜色
        /// </summary>
        public static readonly BindableProperty StrokeProperty =
            BindableProperty.Create("Stroke",
                typeof(Color),
                typeof(Border),
                Color.Default);

        /// <summary>
        /// 边框厚度
        /// </summary>
        public static readonly BindableProperty StrokeThicknessProperty =
            BindableProperty.Create("StrokeThickness",
                typeof(Thickness),
                typeof(Border),
                default(Thickness)
                );

        /// <summary>
        /// 是否裁剪超出部分
        /// </summary>
        public static readonly BindableProperty IsClippedToBorderProperty =
            BindableProperty.Create("IsClippedToBorder",
                typeof(bool),
                typeof(bool),
                true);

        /// <summary>
        /// 圆角大小
        /// </summary>
        public CornerRadius CornerRadius {
            get {
                return (CornerRadius)base.GetValue(CornerRadiusProperty);
            }
            set {
                base.SetValue(CornerRadiusProperty, value);
            }
        }

        /// <summary>
        /// 边框颜色
        /// </summary>
        public Color Stroke {
            get {
                return (Color)GetValue(StrokeProperty);
            }
            set {
                SetValue(StrokeProperty, value);
            }
        }

        /// <summary>
        /// 边框宽度
        /// </summary>
        public Thickness StrokeThickness {
            get {
                return (Thickness)GetValue(StrokeThicknessProperty);
            }
            set {
                SetValue(StrokeThicknessProperty, value);
            }
        }

        /// <summary>
        /// 是否裁剪超出部分
        /// </summary>
        public bool IsClippedToBorder {
            get {
                return (bool)GetValue(IsClippedToBorderProperty);
            }
            set {
                SetValue(IsClippedToBorderProperty, value);
            }
        }

    }
}

uwp renderer class:

using AsNum.XFControls;
using AsNum.XFControls.UWP;
using Xamarin.Forms.Platform.UWP;

[assembly: ExportRenderer(typeof(Border), typeof(BorderRender))]
namespace AsNum.XFControls.UWP
{
    public class BorderRender : ViewRenderer<Border, Windows.UI.Xaml.Controls.Border>
    {

        public BorderRender() : base()
        {
            Loaded += BorderRender_Loaded;
        }

        private void BorderRender_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            if (Control != null)
            {
                SetPadding();
                SetBorderBrush();
                SetThickness();
                SetCornerRadius();
            }
        }

        protected override void OnElementChanged(ElementChangedEventArgs<Border> e)
        {
            base.OnElementChanged(e);
            if (e.NewElement != null)
            {
                var render = Platform.GetRenderer(e.NewElement.Content).GetNativeElement();
                //this line show me error 'Value does not fall within the expected range'
                SetNativeControl(new Windows.UI.Xaml.Controls.Border() { Child = render });
            }
        }

        protected override void UpdateBackgroundColor()
        {
            if (Control != null)
            {
                Control.Background = (Element.BackgroundColor != Xamarin.Forms.Color.Default ?
                                                Element.BackgroundColor.ToBrush() :
                                                base.Background);
            }
        }

        private void SetCornerRadius()
        {
            CornerRadius c = Element.CornerRadius;
            Control.CornerRadius = new Windows.UI.Xaml.CornerRadius(c.TopLeft, c.TopRight, c.BottomRight, c.BottomLeft);
        }

        private void SetBorderBrush()
        {
            Control.BorderBrush = Element.Stroke.ToBrush();
        }

        private void SetThickness()
        {
            Control.BorderThickness = Element.StrokeThickness.ToWinPhone();
        }

        private void SetPadding()
        {
            Control.Padding = Element.Padding.ToWinPhone();
        }

        protected override void UpdateNativeControl()
        {
            base.UpdateNativeControl();
        }

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
        }
    }
}
 <controls:Border Margin="0,10,0,10" CornerRadius="0,10,10,0" BackgroundColor="#5e98d3"  HorizontalOptions="StartAndExpand">
                <Label Text="custom text" TextColor="White"/>
</controls:Border>
kingces95 commented 5 years ago

We don't generally debug custom renderers. Instead, please tell us what deficiencies exist in our first class renderers and we'll open a feature request so that everyone might make use of the functionality.

Ali-YousefiTelori commented 5 years ago

@kingces95 I don't undrestand what you said, there is a bug, I cannot convert my custom border to native control, this code is not working when I want to customize my border class to a nativeborder and set content as normal content, this code work when my border hasn't body:

not work:

                //this line show me error 'Value does not fall within the expected range'
                SetNativeControl(new Windows.UI.Xaml.Controls.Border() { Child = render });

works but no body generated for border (always empty border):

                SetNativeControl(new Windows.UI.Xaml.Controls.Border());