Intereting Posts
Как избавиться от этой черной полосы во время анимации? Iptables в android Как нарисовать дугу между двумя точками на холсте? OkHttp и Retrofit, обновить токен с одновременными запросами Действия пользователя / фрагменты Android для загрузки данных Воспроизведение звуков mp3 с SD-карты Как поддерживать несколько google-service.json в Android Studio Папка Android SDK занимает много места на диске. Нужно ли сохранять все системные изображения? Переопределить экран исходящих вызовов по умолчанию Невозможно сгенерировать подписанный APK с proguard, включенным при использовании Joda Time Android – профилирование определенного потока (поток пользовательского интерфейса) через DDMS Код Bluetooth Low Energy, совместимый с API> = 21 И API <21 Как использовать Active Android с базой данных в памяти для модульных тестов с использованием Robolectric? Android Volley – странная ошибка с кодом HTTP 401- java.io.IOException: не обнаружены проблемы аутентификации Android Spinner с различными макетами для «выпадающего состояния» и «закрытого состояния»?

Принудительное перерисовка 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.)

Во-первых, превратите 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 .