依賴屬性的當前值(Current Value),基值(Base Value)和本地值(Local Value)是MSDN常出現的三個詞,這些屬性和依賴屬性的優先級設置有關。

如下表:

  這裏是當前值

1.  1. 屬性系統強制轉換,這裏是通過依賴屬性的CoerceValueCallback

2.  2. 活動動畫或者具有Hold行為的動畫

  這裏是基值

3.  3. 本地值,通過依賴屬性的SetValue方法,資源,綁定

4.  4. 其他方式如樣式,觸發器等……

當前值

是最外層的屬性值,可能經過一些列的處理或影響而得到的最終值。

基值

當依賴屬性沒有經過系統強制轉換,沒有經過動畫處理影響的值,就是上表中在第三項之上,但沒有被一和二項所影響的值。

本地值

這個是比較直觀設置的值,是通過依賴屬性SetValue方法或者資源或綁定設置的值。

那麼如何得到這些值呢?

當前值:通過依賴屬性的GetValue方法

基值:通過IAnimatable接口的GetAnimationBaseValue方法

本地值:通過依賴屬性的ReadLocalValue方法,如果沒有本地值則返回DependencyProperty.UnsetValue字段

假設有兩個按鈕,名稱分別是btn1和btn2,程序運行後,按鈕的寬度(Width依賴屬性)都會被DoubleAnimation動畫從50變為100,兩個按鈕的唯一區別是btn1的Width是直接設置的。btn2的Width是通過樣式的Setter設置的。

那麼當動畫結束後,兩個按鈕的Width依賴屬性的具體值是這樣的:


btn1

btn2

當前值

100

100

基值

50

50

本地值

50

DependencyProperty.UnsetValue

由於動畫設置了依賴屬性,所以當前值是100.

而在動畫前,Width都是50,所以基值都是50

而btn1直接設置了Width,就是調用了依賴屬性的SetValue,所以本地值被設置。

而btn2通過樣式的Setter設置Width,屬於上表中的第四項,本地值沒有被設置。


 

object[] GetValues(object obj, DependencyProperty pro)
 
        {
 
            if (obj is DependencyObject == false || obj is IAnimatable == false)
 
                throw new ArgumentException();
 
            object[] re = new object[3];
 
 
 
            var dobj = (DependencyObject)obj;
 
            var ianm = (IAnimatable)obj;
 
 
 
            re[0] = dobj.GetValue(pro);
 
            re[1] = ianm.GetAnimationBaseValue(pro);
 
            re[2] = dobj.ReadLocalValue(pro);
 
            return re;
 
 
 
        }
 
 
 
        string GetValuesString(object obj, DependencyProperty pro,string name)
 
        {
 
            var objs = GetValues(obj, pro);
 
            return String.Format("{3}\n當前值:{0}\n基值:{1}\n本地值:{2}\n\n",
 
                objs[0], objs[1], objs[2], name);
 
        }

兩個按鈕XAML動畫定義:

<Button Width="50" Height="30" Name="btn1" Content="1" >
 
            <Button.Triggers>
 
                <EventTrigger RoutedEvent="Button.Loaded">
 
                    <EventTrigger.Actions>
 
                        <BeginStoryboard>
 
                            <Storyboard>
 
                                <DoubleAnimation Storyboard.TargetProperty="Width" 

                                                 To="100" Duration="0:0:0.5"/>
 
                            </Storyboard>
 
                        </BeginStoryboard>
 
                    </EventTrigger.Actions>
 
                </EventTrigger>
 
            </Button.Triggers>
 
        </Button>
 
 
 
        <Button Height="30" Name="btn2" Content="2" >
 
            <Button.Style>
 
                <Style TargetType="Button">
 
                    <Setter Property="Width" Value="50"/>
 
                </Style>
 
            </Button.Style>
 
            <Button.Triggers>
 
                <EventTrigger RoutedEvent="Button.Loaded">
 
                    <EventTrigger.Actions>
 
                        <BeginStoryboard>
 
                            <Storyboard>
 
                                <DoubleAnimation Storyboard.TargetProperty="Width" 

                                                 To="100" Duration="0:0:0.5"/>
 
                            </Storyboard>
 
                        </BeginStoryboard>
 
                    </EventTrigger.Actions>
 
                </EventTrigger>
 
            </Button.Triggers>
 
        </Button>