Windows 8 XAML 綁定引擎極其強大,支援元素間綁定、模型雙向綁定、索引器存取、樣式設值器綁定、RelativeSource 相對源、值轉換器六大進階模式。本文逐一實戰解析,附完整 XAML 與 C# 代碼。
三種模式差異:
INotifyPropertyChanged。<Slider x:Name="sliderOneWay" Minimum="1" Maximum="100" Value="10" Width="180" />
<TextBox Text="{Binding ElementName=sliderOneWay, Path=Value, Mode=OneWay}" Width="150" />
<StackPanel x:Name="root">
<TextBlock x:Name="lblMsg" />
<TextBox Text="{Binding Path=Name, Mode=TwoWay}" />
<TextBox Text="{Binding Age, Mode=TwoWay}" />
<ToggleSwitch Header="性別" OffContent="女" OnContent="男">
<ToggleSwitch.IsOn>
<Binding Path="IsMale" Mode="TwoWay" />
</ToggleSwitch.IsOn>
</ToggleSwitch>
</StackPanel>
// 後端:建立 Model、啟動定時器模擬資料變更
_employee = new Employee { Name="webabcd", Age=33, IsMale=true };
ThreadPoolTimer.CreatePeriodicTimer(t => Dispatcher.RunAsync(..., () =>
{
_employee.Age = random.Next(10,100);
_employee.IsMale = random.Next()%2==0;
}), TimeSpan.FromSeconds(5));
_employee.PropertyChanged += (s,e) => lblMsg.Text = $"屬性 {e.PropertyName} 變更: {_employee.Name},{_employee.Age},{_employee.IsMale}";
root.DataContext = _employee;
<TextBlock Text="{Binding Path=[3]}" /> <!-- List 第 4 項 -->
<TextBlock Text="{Binding Path=[5].Name}" /> <!-- List 第 6 項的 Name -->
<TextBlock Text="{Binding Path=[webabcd]}" /> <!-- 自訂 string 索引器 -->
<TextBlock Text="{Binding Path=[hello]}" /> <!-- Dictionary[key] -->
// 後端設定 DataContext
textBlock.DataContext = list; // List
textBlock2.DataContext = employees; // List
textBlock3.DataContext = this; // 自訂索引器 this[string]
textBlock4.DataContext = dict; // Dictionary
<StackPanel.Resources>
<x:Double x:Key="TextFontSize">24.667</x:Double>
<SolidColorBrush x:Key="TextForeground" Color="#00FF00" />
<Style x:Key="MyStyle" TargetType="TextBox">
<Setter Property="FontSize" Value="{Binding Source={StaticResource TextFontSize}}"/>
<Setter Property="Foreground" Value="{Binding Source={StaticResource TextForeground}}"/>
</Style>
</StackPanel.Resources>
<TextBox Text="我是TextBox" Style="{StaticResource MyStyle}" />
<Style x:Key="MyStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<StackPanel>
<ContentPresenter />
<!-- TemplateBinding 只支援 OneWay,需雙向用 Binding + RelativeSource -->
<Slider Width="{TemplateBinding Width}"
Value="{Binding Content, Mode=TwoWay,
RelativeSource={RelativeSource TemplatedParent}}" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Self:綁定自身屬性 -->
<TextBlock Text="{Binding RelativeSource={RelativeSource Self}, Path=Tag}" Tag="webabcd" />
public sealed class IntegerLetterConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
switch ((double)value) { case 1: return "a"; case 2: return "b"; case 3: return "c"; default: return "unknown"; }
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
switch ((string)value) { case "a": return 1; case "b": return 2; case "c": return 3; default: return 1; }
}
}
<StackPanel.Resources>
<local:IntegerLetterConverter x:Key="IntegerLetterConverter"/>
</StackPanel.Resources>
<Slider x:Name="slider" Minimum="1" Maximum="3" Value="1" Width="180" />
<TextBox Text="{Binding Value, ElementName=slider, Mode=TwoWay,
Converter={StaticResource IntegerLetterConverter},
ConverterParameter=param, ConverterLanguage=zh_cn}" />
注意**:ConverterParameter 與 ConverterLanguage 僅支援靜態值,無法動態綁定。
| 模式 | 適用場景 | 關鍵屬性 |
|---|---|---|
| Element 綁定 | UI 控制項聯動 (Slider↔TextBox、Checkbox↔Panel Visibility) | ElementName, Path, Mode |
| Model 綁定 | 表單編輯、資料呈現、MVVM 核心 | Path, Mode=TwoWay, INotifyPropertyChanged |
| Indexer 綁定 | 集合特定項、字典鍵值、自訂索引器 | Path=[index], Path=[key] |
| Style Setter 綁定 | 主題資源集中管理、設計時樣式參數化 | Value={Binding Source={StaticResource key}} |
| RelativeSource | ControlTemplate 內雙向綁定、自身屬性自引用 | RelativeSource={RelativeSource TemplatedParent/Self} |
| 值轉換器 | 型別轉換、格式化、條件顯示、多值轉換 (IMultiValueConverter) | Converter, ConverterParameter, ConverterLanguage |