我正在尝试创建一个 XF 组件,其某些属性属于从 BindableObject
继承的类型。为了说明,我有类 Shadow
和 double Radius
和 Color ShadowColor
属性和类 MyBoxText
,有一个bool IsLoading
和一个 Shadow Ghost
属性。
我的 View
和它的 Bindings
按预期工作,但我的自定义渲染器有问题:
当我更改 Ghost
属性时,我需要重绘整个 View (MyBoxText
控件),例如,以视觉方式更新阴影颜色。
这里有一些mcve:
类(class)代码:
public class MyBoxText : Label /* It's bindable by inheritance */
{
#region Properties
public static readonly BindableProperty IsLoadingProperty = BindableProperty.Create(nameof(IsLoading), typeof(bool), typeof(MyBoxText), false) ;
public bool IsLoading
{
get { return (bool)GetValue(IsLoadingProperty); }
set { SetValue(IsLoadingProperty, value); }
}
public static readonly BindableProperty GhostProperty = BindableProperty.Create(nameof(Ghost), typeof(Shadow), typeof(MyBoxText), null) ;
public Shadow Ghost
{
get { return (Shadow)GetValue(GhostProperty); }
set { SetValue(GhostProperty, value); }
}
#endregion
}
public class Shadow : BindableObject /* It's explictly bindable */
{
#region Properties
public static readonly BindableProperty ShadowColorProperty = BindableProperty.Create(nameof(ShadowColor), typeof(Color), typeof(Shadow), Color.Black) ;
public Color ShadowColor
{
get { return (Color)GetValue(ShadowColorProperty); }
set { SetValue(ShadowColorProperty, value); }
}
public static readonly BindableProperty ShadowRadiusProperty = BindableProperty.Create(nameof(ShadowRadius), typeof(double), typeof(Shadow), 20) ;
public double ShadowRadius
{
get { return (double)GetValue(ShadowRadiusProperty); }
set { SetValue(ShadowRadiusProperty, value); }
}
#endregion
public Shadow()
{
}
}
我的渲染器的代码是这样的:
public class MyBoxText : LabelRenderer
{
public MyBoxText()
{
SetWillNotDraw(false);
}
public override void Draw(Canvas canvas)
{
MyBoxText myView = (MyBoxText)this.Element;
// Some drawing logic
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == MyBoxText.IsLoadingProperty.PropertyName ||
e.PropertyName == MyBoxText.GhostProperty.PropertyName )
Invalidate();
}
}
问题是,当我更改 Ghost.ShadowColor
属性时,我的“OnElementPropertyChanged”覆盖未被调用,并且 View 在屏幕上保持旧颜色。
有没有办法将 child 的“属性更新”事件传播到父 View “属性已更改”或其他方式来实现这一点?
最佳答案
The issue is that when I change the Ghost.ShadowColor property my 'OnElementPropertyChanged' override is not called, and the View stays with the old color on the screen. Is there a way to propagate the child's 'Property Update' event to parent view 'Property Changed' or another way to achieve this?
是的,有办法。由于您的 Shadow 继承自 BindableObject
,它实现了 INotifyPropertyChanged
接口(interface)。您可以设置通知 ShadowColor
更改:
在 Shadow.cs 中
ShadowColor
的 Setter 添加OnPropertyChanged()
:public class Shadow : BindableObject /* It's explictly bindable */ { #region Properties public static readonly BindableProperty ShadowColorProperty = BindableProperty.Create(nameof(ShadowColor), typeof(Color), typeof(Shadow), Color.Black); public Color ShadowColor { get { return (Color)GetValue(ShadowColorProperty); } set { SetValue(ShadowColorProperty, value); //Notify the ShadowColorProperty Changed OnPropertyChanged(); } } ... }
像这样修改您的
MyBoxText.cs
:public class MyBoxText : Label /* It's bindable by inheritance */ { ... public static readonly BindableProperty GhostProperty = BindableProperty.Create(nameof(Ghost), typeof(Shadow), typeof(MyBoxText), null); public Shadow Ghost { get { return (Shadow)GetValue(GhostProperty); } set { //register the ShadowColor change event value.PropertyChanged += ShadowColor_PropertyChanged; SetValue(GhostProperty, value); } } private void ShadowColor_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { //unregister the event this.Ghost.PropertyChanged -= ShadowColor_PropertyChanged; //set this.Ghost to a new object with new ShadowColor to trigger the OnPropertyChanged this.Ghost = new Shadow { ShadowColor = (sender as Shadow).ShadowColor, ShadowRadius = Ghost.ShadowRadius }; } }
关于c# - 子属性更新调用它的父属性 `OnPropertyChanged`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48992954/