相依屬性在 CLR 屬性基礎上封裝內建行為,賦予聲明式 XAML 強大的動態控制能力,遠勝傳統程式碼撰寫事件處理。
public class MyClass : DependencyObject
{
public static readonly DependencyProperty TestProperty;
static MyClass()
{
TestProperty = DependencyProperty.Register(
"Test", typeof(string), typeof(MyClass),
new PropertyMetadata("Hello, World!", OnTestChanged));
}
private static void OnTestChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
// 值變更回呼
}
public string Test
{
get { return (string)GetValue(TestProperty); }
set { SetValue(TestProperty, value); }
}
}
提示: VS 中輸入 propdp + Tab 可快速產生程式碼片段。
相依屬性值變更自動推播至繫結目標:
<TextBox x:Name="textBox1" />
<Label Content="{Binding ElementName=textBox1, Path=Text}" />
修改 TextBox 文字,Label 即時同步,**無需撰寫任何程式碼**。
<Button x:Name="btnTest">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
滑鼠移入按鈕時,前景色自動變紅。WPF 另提供資料觸發器、事件觸發器。
父元素設定可自動傳遞給所有後代元素(未明確設定者):
<Window FontSize="20">
<Grid>
<TextBox />
<Label Content="Hello" />
<Button Content="Test" />
</Grid>
</Window>
所有子元素字體大小皆為 20。若子元素明確設定 FontSize="10",繼承鏈中斷。
注意: 非所有相依屬性支援繼承(需註冊時指定 FrameworkPropertyMetadataOptions.Inherits)。
同一相依屬性可在多處設定,WPF 依固定優先序決定最終值:
<Button Background="Red">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Green"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Blue" />
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
結果:紅色生效(本地值最高優先序)
| 優先序(高→低) | 來源 |
|---|---|
| 1 | 本地值 |
| 2 | 樣式觸發器 |
| 3 | 樣板觸發器 |
| 4 | 樣式設定器 |
| 5 | 主題樣式觸發器 |
| 6 | 主題樣式設定器 |
| 7 | 屬性值繼承 |
| 8 | 預設值 |
基礎值判斷 → 運算式計算 → 應用動畫 → 強制限制 → 驗證 → 最終結果
ValidateValueCallback 決定值是否合法CoerceValueCallback 限制值範圍(如 9~100)Binding) 需計算結果this.button1.ClearValue(Button.BackgroundProperty);
附加屬性是特殊相依屬性,定義於父類別,使用於子元素:
<DockPanel>
<CheckBox DockPanel.Dock="Top">Hello</CheckBox>
</DockPanel>
<StackPanel TextElement.FontSize="30" TextElement.FontStyle="Bold">
<Button>Help</Button>
<Button>OK</Button>
</StackPanel>
DockPanel.Dock、TextElement.FontSize 皆非子元素原有屬性,透過附加屬性機制實現佈局與樣式擴充。本質上屬 XAML 概念,常用於佈局系統。