子级属性会更新,称为父级的“ OnPropertyChanged” [英] Child properties update calling it's parent's `OnPropertyChanged`
问题描述
我正在尝试创建一个XF组件,该组件的某些属性是从 BindableObject
继承的类型。为了说明,我使用了 Shadow
类,其中 double Radius
和 Color ShadowColor
属性和类 MyBoxText
,它们具有 bool IsLoading
和 Shadow Ghost
属性。
我的视图
和绑定
正常工作,但是我的自定义渲染器存在问题:
当我更改 Ghost
属性时,需要重绘例如,整个视图( MyBoxText
控件的视图)。
这里是一些mcve:
类代码:
public class MyBoxText:Label / *通过继承可绑定* /
{
#region属性
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); }
}
公共静态只读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 / *显式可绑定* /
{
#region Properties
公共静态只读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()
{
}
}
我的渲染器代码如下:
公共类MyBoxText:LabelRenderer
{
public MyBoxText()
{
SetWillNotDraw(false);
}
公共重写void Draw(Canvas canvas)
{
MyBoxText myView =(MyBoxText)this.Element;
//一些绘制逻辑
}
受保护的重写void OnElementPropertyChanged(object sender,PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(发送者,e);
if(e.PropertyName == MyBoxText.IsLoadingProperty.PropertyName ||
e.PropertyName == MyBoxText.GhostProperty.PropertyName)
Invalidate();
}
}
问题是,当我更改 Ghost.ShadowColor
属性不会调用我的'OnElementPropertyChanged'覆盖,并且视图在屏幕上仍保留旧颜色。
有没有一种方法可以将孩子的属性更新事件传播到父视图属性已更改,或者通过另一种方法来实现此目的?
<问题是当我更改Ghost.ShadowColor属性时,不会调用我的'OnElementPropertyChanged'覆盖,并且视图在屏幕上保留旧颜色。
是否可以将孩子的属性更新事件传播到父视图属性已更改,或者通过另一种方法来实现此目的?
是的,有办法。由于您的Shadow继承自 BindableObject
,而后者实现了 INotifyPropertyChanged
接口。您可以设置通知 ShadowColor
更改:
-
添加
OnPropertyChanged()
到Shadow.cs中的ShadowColor
的设置器:public class Shadow:BindableObject / *显式可绑定* /
{
#region属性
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);
//通知ShadowColorProperty已更改
OnPropertyChanged();
}
}
...
}
-
像这样修改您的
MyBoxText.cs
:public class MyBoxText:Label / *通过继承可绑定* /
{
...
public static readonly BindableProperty GhostProperty = BindableProperty.Create(nameof(Ghost),typeof(Shadow ),typeof(MyBoxText),null);
Public Shadow Ghost
{
get {return(Shadow)GetValue(GhostProperty); }
set {
//注册ShadowColor更改事件
的值。PropertyChanged+ = ShadowColor_PropertyChanged;
SetValue(GhostProperty,value); }
}
private void ShadowColor_PropertyChanged(object sender,System.ComponentModel.PropertyChangedEventArgs e)
{
//注销事件
this.Ghost。 PropertyChanged-= ShadowColor_PropertyChanged;
//将this.Ghost设置为具有新ShadowColor的新对象,以触发OnPropertyChanged
this.Ghost = new Shadow
{
ShadowColor =(发送者为Shadow)。ShadowColor,
ShadowRadius = Ghost.ShadowRadius
};
}
}
I'm trying to create a XF component whose some properties are of a type that inherits from BindableObject
. For illustrating, I have class Shadow
with double Radius
and Color ShadowColor
properties and a class MyBoxText
, that have a bool IsLoading
and a Shadow Ghost
properties.
My View
and it's Bindings
is working as expected, but I have an issue with it's custom renderer:
When I change the Ghost
properties I need to redraw the entire view (of the MyBoxText
control), to visually update the shadow color, for example.
Here's some mcve:
Classes code:
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()
{
}
}
My renderer's code is like this:
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();
}
}
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?
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?
Yes, there is a way. Since your Shadow inherits from BindableObject
, which implements the INotifyPropertyChanged
Interface. You can set notify ShadowColor
change:
Add
OnPropertyChanged()
to Setter ofShadowColor
in Shadow.cs: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(); } } ... }
Modify your
MyBoxText.cs
like this: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 }; } }
这篇关于子级属性会更新,称为父级的“ OnPropertyChanged”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!