讓我們想象一下我們想要實現TTT更有娛樂性的一個版本(這是大部分游戲中 最重要的特色)。例如,TTT的一種變體允許玩家每次只能占據3個格子,去除第 一步在下第四步的時候,去除第二步在下第五步的時候,,以此類推。為了實現 這個變體,我們需要保持對每一步按順序跟蹤——可以利用PlayMover類,如示 例5-20。
示例5-20
namespace TicTacToe {
public class PlayerMove {
private string playerName;
public string PlayerName {
get { return playerName; }
set { playerName = value; }
}
private int moveNumber;
public int MoveNumber {
get { return moveNumber; }
set { moveNumber = value; }
}
public PlayerMove(string playerName, int moveNumber) {
this.playerName = playerName;
this.moveNumber = moveNumber;
}
}
}
現在,取代以為每個按鈕對象的內容使用一個簡單的字符串,我們將用示例 5-20中的一個PlayMover實例鮮明顯示這樣的一個改動。
示例5-21
namespace TicTacToe {
public partial class Window1 : Window {
int moveNumber;
void NewGame( ) {
this.moveNumber = 0;
}
void cell_Click(object sender, RoutedEventArgs e) {
// Set button content
//button.Content = this.CurrentPlayer;
button.Content =
new PlayerMove(this.CurrentPlayer, ++this.moveNumber);
}
}
}
圖5-6
正如你回想到的,在第四章,圖5-6所發生的是,按鈕沒有足夠多的信息生成 一個PlayMover對象,但是我們可以通過一個數據模板修復它。
5.5.1數據模板
回憶第四章,WPF允許你定義一個數據模板,這是一棵元素樹,可以在特定的 上下文中擴展。數據模板用於提供一個應用程序生成非可視化外觀對象的能力, 正如示例5-22所示。
示例5-22
<?Mapping XmlNamespace="l" ClrNamespace="TicTacToe" ? >
<Window xmlns:local="local">
<Window.Resources>
<DataTemplate DataType="{x:Type local:PlayerMove}">
<Grid>
<TextBlock
TextContent="{Binding Path=PlayerName}"
FontSize ="32"
FontWeight="Bold"
VerticalAlignment="Center"
HorizontalAlignment="Center" />
<TextBlock
TextContent="{Binding Path=MoveNumber}"
FontSize="16"
FontStyle="Italic"
VerticalAlignment="Bottom"
HorizontalAlignment="Right" />
</Grid>
</DataTemplate>
</Window.Resources>
</Window>
使用在第一章介紹的xaml映射語法,我們將PlayMover類型間接映射到了帶有 xmlns屬性的xaml中,我們將其作為數據模板的數據類型。現在,無論何時WPF遇 到一個PlayMove對象,如我們所有的按鈕內容,數據模板都會展開。在我們這種 情形,這個模板由一個grid組成,其中排列了兩個TextBlock,一個在按鈕中間 顯示玩家名,另一個在按鈕右下位置顯示移動的步數,伴隨著其它的一些設置使 之看起來更漂亮。
5.5.2帶樣式的數據綁定
盡管如此,這些屬性設置深埋在數據模板的很深層。正像這是一個好的想法 將“魔力數字”移出你的代碼,將它們拉出去並給它們一個易於管理的名稱,這 是一個好的想法將成組的設置移動到樣式中,如示例5-23所示。
*將成組的設置移動到樣式中,還顧及皮膚和主題,在第六章會介紹。
示例5-23
<Window.Resources>
<Style x:Key="CellTextStyle" TargetType="{x:Type TextBlock}">
<Setter Property="FontSize" Value="32" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Center" />
</Style>
<Style x:Key="MoveNumberStyle" TargetType="{x:Type TextBlock}">
<Setter Property="FontSize" Value="16" />
<Setter Property="FontStyle" Value="Italic" />
<Setter Property="VerticalAlignment" Value="Bottom" />
<Setter Property="HorizontalAlignment" Value="Right" />
</Style>
<DataTemplate DataType="{x:Type l:PlayerMove}">
<Grid>
<TextBlock
TextContent="{Binding Path=PlayerName}"
Style="{StaticResource CellTextStyle}" />
<TextBlock
TextContent="{Binding Path=MoveNumber}"
Style="{StaticResource MoveNumberStyle}" />
</Grid>
</DataTemplate>
</Window.Resources>
使用樣式是很通常的,從而可以使用數據模板設置成組的屬性,創建帶有大 量屬性的大量元素。圖5-7顯示了這個結果。
圖5-7
仍然,像圖5-7一樣漂亮,交互作用是一種WPF給予的令人厭煩的能力。讓我 們看一下使用在應用程序中使用樣式屬性我們都能做些什麼。