CPF C#跨平台桌面UI框架
系列教程
CPF 入门教程 - 属性和事件(七)
依赖属性
CpfObject相当于WPF里的DependencyObject依赖对象。继承该类的对象,所有属性默认都是依赖属性
依赖属性有什么用?支持属性变化通知,数据绑定,触发器,动画等等。
属性写法:
/// <summary> /// 绑定的数据上下文 /// </summary> [PropertyMetadata(null)] public virtual object DataContext { get { return GetValue<object>(); } set { SetValue(value); } } /// <summary> /// 前景色 /// </summary> [UIPropertyMetadata(typeof(ViewFill), "Black", UIPropertyOptions.AffectsRender)] public ViewFill Foreground { get { return (ViewFill)GetValue(); } set { SetValue(value); } }
属性上的特性可以是 PropertyMetadata或者UIPropertyMetadata 中的一个,默认值建议通过这两个特性来设置。如果不加这两个特性,那默认值就是null或者0,属性不能是private,否则子类无法使用该属性,
子类不能用new的方式来覆盖属性
如果是复杂属性类型默认值,可以通过重写 OnOverrideMetadata 来设置
protected override void OnOverrideMetadata(OverrideMetadata overridePropertys) { base.OnOverrideMetadata(overridePropertys); overridePropertys.Override("StrokeStyle", new UIPropertyMetadataAttribute(new Stroke(1))); }
如果不希望声明为依赖属性,上面加[NotCpfProperty]
[NotCpfProperty] public bool IsMeasureValid { get; private set; }
附加属性:
特殊的依赖属性,用来做特殊功能的标记
/// <summary> /// 获取或设置元素行索引 /// </summary> public static Attached<int> RowIndex { get { return CpfObject.RegisterAttached(0); } } Grid.RowIndex(control, 1);//使用附加属性方式设置行索引 var index = Grid.RowIndex(control);//获取附加属性值 control.Attacheds.Add(Grid.ColumnIndex, 0); //附加属性的设置和绑定 new Border { Attacheds={ { Grid.ColumnIndex, 0,nameof(TabStripPlacement),this}}, }
计算属性
计算属性来自Vue里的computed 可绑定,只读属性
当SelectValue或者TextSize属性值变化之后导致TestComputedProperty属性值变化,有提供属性通知
[Computed(nameof(SelectValue), nameof(TextSize))] public string TestComputedProperty { get { return SelectValue == null ? "" : SelectValue.ToString() + TextSize; } }
属性通知
如果是对象自己内部绑定,定义个方法,上面加个PropertyChanged(通知的属性名)就行,方法参数必须是
(object newValue, object oldValue, PropertyMetadataAttribute attribute)
PropertyChanged可以加多个,相当于绑定到多个属性通知事件
[PropertyChanged(nameof(MarginBottom))] [PropertyChanged(nameof(MarginLeft))] [PropertyChanged(nameof(MarginRight))] [PropertyChanged(nameof(MarginTop))] void RegisterMargin(object newValue, object oldValue, PropertyMetadataAttribute attribute) { }
一般不建议用重写 OnPropertyChanged的方式来处理属性变化事件
如果外部的话,绑定PropertyChanged事件,通过事件数据CPFPropertyChangedEventArgs来判断属性和获取属性数据
事件定义
CpfObejct里的事件定义,弱引用事件,并且不会被重复绑定
public event EventHandler<RoutedEventArgs> DoubleClick { add { AddHandler(value); } remove { RemoveHandler(value); } } RaiseEvent(e, nameof(DoubleClick));//触发事件
由于是弱引用的,所以不能采用Lambda方式来绑定事件,因为可能会被回收导致绑定失效
比如这种写法this.Click+=(s,e)=>{…};