Intereting Posts
Настройка приоритета WiFi на Android Lollipop или позже через интерфейс настроек Создание пользовательских больших уведомлений Android-приложение вылетает с NullPointerException в ChoreoGrapher Android, как выполнить sql-файл в sqlitedatabase Как получить URI видео HTML5 в HTML5VFullScreen $ SurfaceVideoView в Android 4.0? Переход на Android-уровень Api от 23 до 22 в консоли разработчика Я не могу удалить японский IME с моего эмулятора Android Пространства имен Javascript в Android JavascriptInterface Метод jsonObject.addProperty добавляет ненужные значения котировок и слэшей к его значению Как определить исходящий звонок в Android с помощью класса Visualizer? Объединение файлов манифеста Android, конфликтный фильтр Правильное расширение LinearLayout для создания пользовательского представления Как отправить текстовое сообщение в android через sip Как вставить запись SQLite с установленным значением «сейчас» в приложении Android? Как избежать тоста, если уже есть один тост

Принудительное перерисовка Xamarin.Forms View с помощью настраиваемого средства визуализации

У меня есть визуальный элемент MyButton с настраиваемым визуализатором, реализованным для iOS.

Общий:

 namespace RendererTest { public class MyButton: Button { public Color BoundaryColor { get; set; } } public static class App { public static Page GetMainPage() { var button = new MyButton { Text = "Click me!", BoundaryColor = Color.Red }; button.Clicked += (sender, e) => (sender as MyButton).BoundaryColor = Color.Blue; return new ContentPage { Content = button }; } } } 

IOS:

 [assembly:ExportRenderer(typeof(MyButton), typeof(MyButtonRenderer))] namespace RendererTest.iOS { public class MyButtonRenderer: ButtonRenderer { public override void Draw(RectangleF rect) { using (var context = UIGraphics.GetCurrentContext()) { context.SetFillColor(Element.BackgroundColor.ToCGColor()); context.SetStrokeColor((Element as MyButton).BoundaryColor.ToCGColor()); context.SetLineWidth(10); context.AddPath(CGPath.FromRect(Bounds)); context.DrawPath(CGPathDrawingMode.FillStroke); } } } } 

При нажатии кнопки красная граница должна стать синей. По-видимому, рендер не замечает измененное свойство. Как я могу вызвать перерисовку?

(Этот пример для iOS. Но мой вопрос относится и к Android.)

Solutions Collecting From Web of "Принудительное перерисовка Xamarin.Forms View с помощью настраиваемого средства визуализации"

Во-первых, превратите BoundaryColor в свойство bindable. Этого не требуется, достаточно INPC событие INPC , но тогда вы можете привязать его:

 public static readonly BindableProperty BoundaryColorProperty = BindableProperty.Create ("BoundaryColor", typeof(Color), typeof(MyButton), Color.Default); public Color BoundaryColor { get { return (Color)GetValue (BoudaryColorProperty); } set { SetValue (BoundaryColorProperty, value); } } 

То в вашем рендерере:

 protected override void OnElementPropertyChanged (object sender, PropertyChangedEventArgs e) { base.OnElementPropertyChanged (sender, e); if (e.PropertyName == MyButton.BoundaryColorProperty.PropertyName) SetNeedsDisplay (); } 

Требуются две модификации:

  1. Вызовите OnPropertyChanged в OnPropertyChanged свойства BoundaryColor :

     public class MyButton: Button { Color boundaryColor = Color.Red; public Color BoundaryColor { get { return boundaryColor; } set { boundaryColor = value; OnPropertyChanged(); // <-- here } } } 
  2. Подпишитесь на мероприятие в методе MyButtonRenderer :

     public class MyButtonRenderer: ButtonRenderer { protected override void OnElementChanged(ElementChangedEventArgs<Button> e) { base.OnElementChanged(e); Element.PropertyChanged += (s_, e_) => SetNeedsDisplay(); // <-- here } public override void Draw(RectangleF rect) { // ... } } 

Примечание. Кажется, важно подписаться внутри OnElementChanged а не на конструктор. В противном случае возникает System.Reflection.TargetInvocationException .