[英]System.ArgumentException: 'Not a valid default value Parameter name: defaultValue' (NControl)
I am trying to implement a button with a gradient occupying the NControl and NGraphics plugin我正在尝试实现一个带有渐变的按钮,占据 NControl 和 NGraphics 插件
To do this I created a folder named Controls in my shared project, within it I created a class called GradientButton which inherits from NControlView (using NControl.Abstractions;) and contains all the methods and commands to be binded in the view为此,我在我的共享项目中创建了一个名为 Controls 的文件夹,在其中我创建了一个名为 GradientButton 的 class,它继承自 NControlView(使用 NControl.Abstractions;)并包含要在视图中绑定的所有方法和命令
GradientButton.CS:渐变按钮.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);
}
}
}
Then in my XAML view I declare the custom property to be able to use the control and use the button and its properties然后在我的 XAML 视图中,我声明自定义属性能够使用控件并使用按钮及其属性
LOGINVIEW.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>
But when starting the project and trying to show the view my application bursts with the following error on the screen但是当启动项目并尝试显示视图时,我的应用程序在屏幕上突然出现以下错误
System.ArgumentException: 'Not a valid default value Parameter name: defaultValue' System.ArgumentException:'不是有效的默认值参数名称:defaultValue'
I do not understand what is the value that I am not initializing and when trying to see the StackTrace it gives me very little information about the error我不明白我没有初始化的值是什么,当试图查看 StackTrace 时,它给我的错误信息很少
When you continue debugging after the first error, it shows a second in the LoginView in the code behind当您在第一个错误后继续调试时,它会在后面的代码中的 LoginView 中显示第二个
What am I doing wrong?我究竟做错了什么? What am I forgetting to initialize?我忘记初始化什么? Any help for me?对我有什么帮助吗?
The error comes for the lack of a DefaultValue when creating the BindableProperties for the Colors: StartColorProperty
and EndColorProperty
.为 Colors: StartColorProperty
和EndColorProperty
创建 BindableProperties 时缺少 DefaultValue 错误。
Change the Create method of these two BindableProperties and add a DefaultValue .更改这两个 BindableProperties 的 Create 方法并添加一个DefaultValue 。 If you don't want to use anything just use the Color.Default
, something like this:如果您不想使用任何东西,只需使用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;
});
Hope this helps.-希望这可以帮助。-
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.