CPF 入門教程 – 屬性和事件(七)

CPF C#跨平台桌面UI框架

 

系列教程

CPF 入門教程(一)

CPF 門教程 – 數據綁定和命令綁定(二)

CPF 入門教程 – 樣式和動畫(三)

CPF 入門教程 – 繪圖(四) 

CPF 入門教程 – 設計器和模板庫的使用(五)

CPF 入門教程 – 控制項布局(六) 

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)=>{…};