依賴屬性的當前值(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>