WPF 的資料樣板 (DataTemplate) 賦予資料呈現極大彈性,配合值轉換器 (IValueConverter) 更能實現型別轉換與條件式顯示。本文將示範如何定義可重複使用的樣板、使用 DataType 自動匹配、利用觸發器與轉換器達成動態 UI 效果。
直接在 ListBox.ItemTemplate 定義 DataTemplate,即可自訂每個項目的顯示結構。
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Name}" />
<TextBlock Text=", " />
<TextBlock Text="{Binding Path=Age}" />
<TextBlock Text=", " />
<TextBlock Text="{Binding Path=Sex}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
將樣板放入 Window.Resources,透過 x:Key 供多處引用。
<DataTemplate x:Key="myData"> ... </DataTemplate>
<ListBox ItemTemplate="{StaticResource myData}" />
設定 DataType="{x:Type my:Personal}",所有 Personal 型別資料自動套用此樣板,無需在控制項指定 ItemTemplate。
<DataTemplate DataType="{x:Type my:Personal}"> ... </DataTemplate>
在樣板內使用 DataTrigger,依資料屬性值動態變更 UI 元素屬性。例如:依性別顯示不同邊框顏色。
<DataTemplate DataType="{x:Type my:Personal}">
<Border x:Name="border1" BorderBrush="Red" BorderThickness="1" Padding="5" Margin="5">
<StackPanel Orientation="Horizontal"> ... </StackPanel>
</Border>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=Sex}" Value="Male">
<Setter TargetName="border1" Property="BorderBrush" Value="Blue" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>

實作 IValueConverter 介面,即可在繫結管線中轉換資料型別或格式。
public class SexConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value.ToString() == "Male" ? "男" : "女";
}
public object ConvertBack(...) { throw new NotImplementedException(); }
}
XAML 中引用:
<my:SexConverter x:Key="sexConverter" />
<TextBlock Text="{Binding Path=Sex, Converter={StaticResource sexConverter}}" />
Binding.DoNothing回傳 Binding.DoNothing 會暫時取消該繫結,不同於回傳 null(null 為有效值)。
將性別轉為 Brush,直接套用於 Border.BorderBrush,效果等同觸發器但更靈活。
public class SexToBrushConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value.ToString() == "Male" ? Brushes.Blue : Brushes.Red;
}
...
}
<Border BorderBrush="{Binding Path=Sex, Converter={StaticResource sexToBrushConverter}}" ... />
