System.ArgumentException: «Недопустимое значение по умолчанию Имя параметра: defaultValue» (NControl) - PullRequest
0 голосов
/ 20 октября 2019

Я пытаюсь реализовать кнопку с градиентом, занимающую плагин NControl и NGraphics

Для этого я создал папку с именем Controls в своем общем проекте, в котором я создал класс с именем GradientButton, который наследуется отNControlView (с использованием NControl.Abstractions;) и содержит все методы и команды, которые должны быть связаны в представлении

Infraestructure

GradientButton.CS:

using NControl.Abstractions;
using NGraphics;
using System.Collections.Generic;
using System.Windows.Input;
using Xamarin.Forms;
using Color = Xamarin.Forms.Color;
using Point = NGraphics.Point;
using TextAlignment = Xamarin.Forms.TextAlignment;

namespace SoftwareCore.Forms.Controls
{

    public class GradientButton : NControlView
    {
        private readonly Label _label;
        private readonly NControlView _background;

        public GradientButton()
        {
            HeightRequest = 44;
            WidthRequest = 100;

            _label = new Label
            {
                Text = Text,
                TextColor = TextColor,
                FontSize = 17,
                BackgroundColor = Color.Transparent,
                HorizontalTextAlignment = TextAlignment.Center,
                VerticalTextAlignment = TextAlignment.Center
            };

            _background = new NControlView
            {
                DrawingFunction = (canvas, rect) =>
                {
                    var brush = new LinearGradientBrush(
                        Point.Zero,
                        Point.OneX,
                        StartColor.ToNColor(),
                        EndColor.ToNColor());

                    var curveSize = BorderRadius;
                    var width = rect.Width;
                    var height = rect.Height;

                    canvas.DrawPath(new PathOp[]{
                        new MoveTo(curveSize, 0),
                        // Top Right corner
                        new LineTo(width-curveSize, 0),
                        new CurveTo(
                            new Point(width-curveSize, 0),
                            new Point(width, 0),
                            new Point(width, curveSize)
                        ),
                        new LineTo(width, height-curveSize),
                        // Bottom right corner
                        new CurveTo(
                            new Point(width, height-curveSize),
                            new Point(width, height),
                            new Point(width-curveSize, height)
                        ),
                        new LineTo(curveSize, height),
                        // Bottom left corner
                        new CurveTo(
                            new Point(curveSize, height),
                            new Point(0, height),
                            new Point(0, height-curveSize)
                        ),
                        new LineTo(0, curveSize),
                        new CurveTo(
                            new Point(0, curveSize),
                            new Point(0, 0),
                            new Point(curveSize, 0)
                        ),
                        new ClosePath()
                    }, null, brush);


                }
            };

            Content = new Grid
            {
                Children = {
                    _background,
                    _label
                }
            };
        }

        public Color StartColor
        {
            get => (Color)GetValue(StartColorProperty);
            set
            {
                SetValue(StartColorProperty, value);
                Invalidate();
            }
        }

        public Color EndColor
        {
            get => (Color)GetValue(EndColorProperty);
            set
            {
                SetValue(EndColorProperty, value);
                Invalidate();
            }
        }

        public static BindableProperty StartColorProperty =
            BindableProperty.Create(nameof(StartColor), typeof(Color), typeof(GradientButton), defaultBindingMode: BindingMode.OneWay,
                propertyChanged: (b, o, n) =>
                {
                    var ctrl = (GradientButton)b;
                    ctrl.StartColor = (Color)n;
                });
        public static BindableProperty EndColorProperty =
            BindableProperty.Create(nameof(EndColor), typeof(Color), typeof(GradientButton), defaultBindingMode: BindingMode.OneWay,
                propertyChanged: (b, o, n) =>
                {
                    var ctrl = (GradientButton)b;
                    ctrl.EndColor = (Color)n;
                });

        public int BorderRadius
        {
            get => (int)GetValue(BorderRadiusProperty);
            set
            {
                SetValue(BorderRadiusProperty, value);
                Invalidate();
            }
        }
        public const int DefaultRadius = 40;
        public static BindableProperty BorderRadiusProperty =
            BindableProperty.Create(nameof(BorderRadius), typeof(int), typeof(GradientButton), DefaultRadius, BindingMode.OneTime,
                propertyChanged: (b, o, n) =>
                {
                    var ctrl = (GradientButton)b;
                    ctrl.BorderRadius = (int)n;
                });

        public string Text
        {
            get => GetValue(TextProperty) as string;
            set
            {
                SetValue(TextProperty, value);
                _label.Text = value;
                Invalidate();
            }
        }

        public static BindableProperty TextProperty =
            BindableProperty.Create(nameof(Text), typeof(string), typeof(GradientButton), defaultBindingMode: BindingMode.OneWay,
                propertyChanged: (b, o, n) =>
                {
                    var ctrl = (GradientButton)b;
                    ctrl.Text = (string)n;
                });

        public Color TextColor
        {
            get => (Color)GetValue(TextColorProperty);
            set
            {
                SetValue(TextColorProperty, value);
                _label.TextColor = value;
                Invalidate();
            }
        }

        public static BindableProperty TextColorProperty =
            BindableProperty.Create(nameof(TextColor), typeof(Color), typeof(GradientButton), defaultBindingMode: BindingMode.OneWay,
                propertyChanged: (b, o, n) =>
                {
                    var ctrl = (GradientButton)b;
                    ctrl.TextColor = (Color)n;
                });

        public static BindableProperty CommandProperty =
            BindableProperty.Create(nameof(Command), typeof(ICommand), typeof(GradientButton), defaultBindingMode: BindingMode.OneWay,
                propertyChanged: (bindable, oldValue, newValue) =>
                {
                    var ctrl = (GradientButton)bindable;
                    ctrl.Command = (ICommand)newValue;
                });

        public ICommand Command
        {
            get => (ICommand)GetValue(CommandProperty);
            set => SetValue(CommandProperty, value);
        }

        public static BindableProperty CommandParameterProperty =
            BindableProperty.Create(nameof(CommandParameter), typeof(object), typeof(GradientButton), defaultBindingMode: BindingMode.TwoWay,
                propertyChanged: (bindable, oldValue, newValue) =>
                {
                    var ctrl = (GradientButton)bindable;
                    ctrl.CommandParameter = newValue;
                });

        //private readonly Label _label;
        //private readonly NControlView _background;

        public object CommandParameter
        {
            get => GetValue(CommandParameterProperty);
            set => SetValue(CommandParameterProperty, value);
        }

        public override bool TouchesBegan(IEnumerable<Point> points)
        {
            base.TouchesBegan(points);
            this.ScaleTo(0.96, 65, Easing.CubicInOut);
            return true;
        }

        public override bool TouchesCancelled(IEnumerable<Point> points)
        {
            base.TouchesCancelled(points);
            this.ScaleTo(1.0, 65, Easing.CubicInOut);
            return true;
        }

        public override bool TouchesEnded(IEnumerable<Point> points)
        {
            base.TouchesEnded(points);
            this.ScaleTo(1.0, 65, Easing.CubicInOut);
            if (Command != null && Command.CanExecute(CommandParameter))
                Command.Execute(CommandParameter);

            return true;
        }
    }

    public static class ColorHelpers
    {
        public static NGraphics.Color ToNColor(this Color color)
        {
            return new NGraphics.Color(color.R, color.G, color.B, color.A);
        }
    }
}

Затем в моем представлении XAML я заявляю, что пользовательское свойство может использовать элемент управления и использовать кнопку и ее свойства

LOGINVIEW.XAML:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:controls="clr-namespace:SoftwareCore.Forms.Controls"
             BindingContext="{Binding Main, Source={StaticResource Locator}}"
             x:Class="SoftwareCore.Forms.Views.LoginView"
             Title="Login">


        <StackLayout
                BindingContext="{Binding Login}"
                Padding="8">

            <StackLayout
                    Orientation="Horizontal">

                    <controls:GradientButton
                                Margin="10"
                                BorderRadius="20"
                                EndColor="#5a41b9"
                                HorizontalOptions="FillAndExpand"
                                StartColor="#6C6FEC"
                                Text="Get started"
                                TextColor="White" />        

            </StackLayout>
        </StackLayout>
</ContentPage>

Но когдазапускает проект и пытается показать представление, которое мое приложение разрывает со следующей ошибкой на экране

Error

System.ArgumentException: «Недопустимое значение по умолчанию Имя параметра: defaultValue '

Я не понимаю, какое значение я не инициализирую, и когда я пытаюсь увидеть StackTrace, мне это очень нравится. Информация об ошибке

Local

Когда вы продолжаете отладку после первой ошибки, она показывает секунду в LoginView в коде, стоящем за

LoginView LoginView Error

Что я делаю не так? Что я забыл инициализировать? Любая помощь для меня?

1 Ответ

1 голос
/ 20 октября 2019

Ошибка возникает из-за отсутствия DefaultValue при создании BindableProperties для цветов: StartColorProperty и EndColorProperty.

Измените метод Create этих двух BindableProperties и добавьте DefaultValue . Если вы не хотите ничего использовать, просто используйте Color.Default, что-то вроде этого:

public static BindableProperty StartColorProperty =
    BindableProperty.Create(nameof(StartColor), typeof(Color), typeof(GradientButton), defaultValue: Color.Default, defaultBindingMode: BindingMode.OneWay,
        propertyChanged: (b, o, n) =>
        {
            var ctrl = (GradientButton)b;
            ctrl.StartColor = (Color)n;
        });

public static BindableProperty EndColorProperty =
    BindableProperty.Create(nameof(EndColor), typeof(Color), typeof(GradientButton), defaultValue: Color.Default, defaultBindingMode: BindingMode.OneWay,
        propertyChanged: (b, o, n) =>
        {
            var ctrl = (GradientButton)b;
            ctrl.EndColor = (Color)n;
        });

Надеюсь, это поможет .-

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...