Я реализовал пользовательский макет, основная характеристика которого c заключается в том, что фон может быть градиентом, давая 2 шестнадцатеричных цвета. Сам вид прекрасно работает, проблема в том, что изменения, сделанные в этих двух цветах во время работы программы, не отражают себя в приложении, пользовательский макет получает и изменяет оба новых цвета и правильно создает градиент, но это не так показать сделанные изменения. Я предполагаю, что проблема в том, что я неправильно реализовал I INotifyPropertyChanged.
Вот код моего пользовательского представления:
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Xamarin.Forms;
namespace MyProject.Renderers
{
public class GradientLayout : StackLayout, INotifyPropertyChanged
{
public string ColorsList { get; set; }
public Color[] Colors
{
get
{
//colorsList have the following format: "HexCode1,HexCode2"
string[] hex = ColorsList.Split(',');
Color[] colors = new Color[hex.Length];
for (int i = 0; i < hex.Length; i++)
{
colors[i] = Color.FromHex(hex[i].Trim());
}
return colors;
}
}
//since this is a property that I am not trying to modify, I will not provide the rest of its code to make this as simple as possible.
public GradientColorStackMode Mode { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
И это все, если вам нужна дополнительная информация Я предоставлю его, как только увижу ваш запрос, спасибо всем за потраченное время, надеюсь, у вас будет хороший день.
РЕДАКТИРОВАТЬ: Здесь у вас есть класс в myProject . ios, который связан с фоновым градиентом.
[assembly: ExportRenderer(typeof(GradientLayout), typeof(GradientLayoutRenderer))]
namespace MyProject.iOS.Renderers
{
public class GradientLayoutRenderer : VisualElementRenderer<StackLayout>
{
public override void Draw(CGRect rect)
{
base.Draw(rect);
GradientLayout layout = (GradientLayout)Element;
CGColor[] colors = new CGColor[layout.Colors.Length];
for (int i = 0, l = colors.Length; i < l; i++)
{
colors[i] = layout.Colors[i].ToCGColor();
}
var gradientLayer = new CAGradientLayer();
switch (layout.Mode)
{
default:
case GradientColorStackMode.ToRight:
gradientLayer.StartPoint = new CGPoint(0, 0.5);
gradientLayer.EndPoint = new CGPoint(1, 0.5);
break;
case GradientColorStackMode.ToLeft:
gradientLayer.StartPoint = new CGPoint(1, 0.5);
gradientLayer.EndPoint = new CGPoint(0, 0.5);
break;
case GradientColorStackMode.ToTop:
gradientLayer.StartPoint = new CGPoint(0.5, 0);
gradientLayer.EndPoint = new CGPoint(0.5, 1);
break;
case GradientColorStackMode.ToBottom:
gradientLayer.StartPoint = new CGPoint(0.5, 1);
gradientLayer.EndPoint = new CGPoint(0.5, 0);
break;
case GradientColorStackMode.ToTopLeft:
gradientLayer.StartPoint = new CGPoint(1, 0);
gradientLayer.EndPoint = new CGPoint(0, 1);
break;
case GradientColorStackMode.ToTopRight:
gradientLayer.StartPoint = new CGPoint(0, 1);
gradientLayer.EndPoint = new CGPoint(1, 0);
break;
case GradientColorStackMode.ToBottomLeft:
gradientLayer.StartPoint = new CGPoint(1, 1);
gradientLayer.EndPoint = new CGPoint(0, 0);
break;
case GradientColorStackMode.ToBottomRight:
gradientLayer.StartPoint = new CGPoint(0, 0);
gradientLayer.EndPoint = new CGPoint(1, 1);
break;
}
gradientLayer.Frame = rect;
gradientLayer.Colors = colors;
NativeView.Layer.InsertSublayer(gradientLayer, 0);
}
}
}
EDIT: Также вот код xaml и xaml.cs, связанный с объявлением и вызовом макета градиента. XAML.CS:
page.ColorsList = Items[0].StartColor+","+Items[0].EndColor;
page.Mode = MyProject.Renderers.GradientColorStackMode.ToBottomLeft;
XAML:
<renderers:GradientLayout
x:Name="page"
Opacity="0"
Mode="ToBottomLeft">
</renders:GradientLayout>
РЕДАКТИРОВАТЬ: Я пытался реализовать Junior Jiang´s, после того, как я это сделал, я заметил 1 изменение, класс IOS выполнялся до конструктора моего класса xaml.cs, давая мне в string[] hex = ColorsList.Split(',');
ту же ошибку, что я упоминал ранее, потому что ColorsList не получил никакого значения, поэтому я присвоил 2 значения по умолчанию для «colors» и реализовал условие, чтобы убедиться, что код конструктора не был выполнен с ColorsList, равным нулю:
public GradientLayout()
{
if(colorsList != null)
{
//colorsList have the following format: "HexCode1,HexCode2"
string[] hex = ColorsList.Split(',');
colors = new Color[hex.Length];
for (int i = 0; i < hex.Length; i++)
{
colors[i] = Color.FromHex(hex[i].Trim());
}
// BindingContext = this;
}
else
{
colors = new Color[2];
colors[0] = Color.FromHex("#000000");
colors[1] = Color.FromHex("#000000");
}
}
После этого выполнение кода не дало никаких ошибок, но он не работал должным образом, так как только класс IOS вызывает класс 1 раз (при построении представления). Я также ничего не связывал, потому что я не понимаю, что я должен делать в //BindingContext = this