![](/img/trans.png)
[英]Entry Custom Renderer(add all borders for Android) in Xamarin.Forms
[英]Force redraw of Xamarin.Forms View with custom renderer
我有一个可视元素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
转换为可绑定属性。 这不是必需的,触发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 ();
}
需要进行两项修改:
在BoundaryColor
属性的setter中调用OnPropertyChanged
:
public class MyButton: Button { Color boundaryColor = Color.Red; public Color BoundaryColor { get { return boundaryColor; } set { boundaryColor = value; OnPropertyChanged(); // <-- here } } }
在MyButtonRenderer
的OnElementChanged
方法中订阅事件:
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
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.