Градиентный стек OnElementPropertyChanged не работает в формах Xamarin

#c# #xamarin #xamarin.forms #gradient

#c# #xamarin #xamarin.forms #градиент

Вопрос:

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

Мой пользовательский GradientColorStackRenderer:

 [assembly: ExportRenderer(typeof(GradientColorStack), typeof(GradientColorStackRenderer))]

namespace GradientColor.Droid
{
    
    public class GradientColorStackRenderer : VisualElementRenderer<StackLayout>
    {
        public Color StartColor { get; set; }
        public Color EndColor { get; set; }
        protected override void DispatchDraw(global::Android.Graphics.Canvas canvas)
        {
            #region for Vertical Gradient
            var gradient = new Android.Graphics.LinearGradient(0, 0, 0, Height,
            #endregion

            #region for Horizontal Gradient
                    // var gradient = new Android.Graphics.LinearGradient(0, 0, Width, 0,
            #endregion

                    this.StartColor.ToAndroid(),
                    this.EndColor.ToAndroid(),
                    Android.Graphics.Shader.TileMode.Mirror);

            var paint = new Android.Graphics.Paint()
            {
                Dither = true,
            };
            paint.SetShader(gradient);
            canvas.DrawPaint(paint);
            base.DispatchDraw(canvas);
        }

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

            if (e.OldElement != null || Element == null)
            {
                return;
            }
            try
            {
                var stack = e.NewElement as GradientColorStack;
                this.StartColor = stack.StartColor;
                this.EndColor = stack.EndColor;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(@"ERROR:", ex.Message);
            }
        }


        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);
            if (e.PropertyName == "StartColor" || e.PropertyName  == "EndColor")
            {
                var stack = sender as GradientColorStack;
                this.StartColor = stack.StartColor;
                this.EndColor = stack.EndColor;
            }
        }

    }
}
  

Мой метод

  private void Button_Clicked(object sender, EventArgs e)
        {
          
          
            lytBack.StartColor = Color.Red;
            lytBack.EndColor = Color.Blue;
            lytBack.Opacity = 1;
        }
  

Мой XAML

 <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Randomage.MainPage"
             xmlns:local="clr-namespace:GradientColor; assembly:GradientColor" 
             >

    <local:GradientColorStack  x:Name="lytBack" StartColor="#ffc3a0" EndColor="#ffafbd"   Spacing="0" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
  
    </local:GradientColorStack>
</ContentPage>
  

Цвет фона появляется при запуске приложения, но проблема в том, что я не могу изменить его после. Цвет фона появляется при запуске приложения, но проблема в том, что я не могу изменить его после.

Комментарии:

1. градиенты теперь поддерживаются непосредственно в формах — devblogs.microsoft.com/xamarin /…

2. Попробуйте использовать внутри устройства. BeginInvokeOn основной поток

Ответ №1:

Вы обнаруживаете изменения свойств в вашем средстве визуализации Android, однако вы не выполняете перерисовку, чтобы их можно было использовать.

Изменить:-

     protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);
        if (e.PropertyName == "StartColor" || e.PropertyName  == "EndColor")
        {
            var stack = sender as GradientColorStack;
            this.StartColor = stack.StartColor;
            this.EndColor = stack.EndColor;
        }
    }
  

Для:-

     protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);
        if (e.PropertyName == "StartColor" || e.PropertyName  == "EndColor")
        {
            var stack = sender as GradientColorStack;
            this.StartColor = stack.StartColor;
            this.EndColor = stack.EndColor;
            //
            this.Invalidate();
        }
    }
  

это.Invalidate() заставляет выполнить перерисовку.