且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

《Programming WPF》翻译 第5章 5.数据模板和样式

更新时间:2022-08-12 17:30:30

原文:《Programming WPF》翻译 第5章 5.数据模板和样式

让我们想象一下我们想要实现TTT更有娱乐性的一个版本(这是大部分游戏中最重要的特色)。例如,TTT的一种变体允许玩家每次只能占据3个格子,去除第一步在下第四步的时候,去除第二步在下第五步的时候,,以此类推。为了实现这个变体,我们需要保持对每一步按顺序跟踪——可以利用PlayMover类,如示例5-20

示例5-20

《Programming WPF》翻译 第5章 5.数据模板和样式《Programming WPF》翻译 第5章 5.数据模板和样式namespace TicTacToe 《Programming WPF》翻译 第5章 5.数据模板和样式{
《Programming WPF》翻译 第5章 5.数据模板和样式《Programming WPF》翻译 第5章 5.数据模板和样式  
public class PlayerMove 《Programming WPF》翻译 第5章 5.数据模板和样式{
《Programming WPF》翻译 第5章 5.数据模板和样式    
private string playerName;
《Programming WPF》翻译 第5章 5.数据模板和样式《Programming WPF》翻译 第5章 5.数据模板和样式    
public string PlayerName 《Programming WPF》翻译 第5章 5.数据模板和样式{
《Programming WPF》翻译 第5章 5.数据模板和样式《Programming WPF》翻译 第5章 5.数据模板和样式      
get 《Programming WPF》翻译 第5章 5.数据模板和样式return playerName; }
《Programming WPF》翻译 第5章 5.数据模板和样式《Programming WPF》翻译 第5章 5.数据模板和样式      
set 《Programming WPF》翻译 第5章 5.数据模板和样式{ playerName = value; }
《Programming WPF》翻译 第5章 5.数据模板和样式    }

《Programming WPF》翻译 第5章 5.数据模板和样式
《Programming WPF》翻译 第5章 5.数据模板和样式    
private int moveNumber;
《Programming WPF》翻译 第5章 5.数据模板和样式《Programming WPF》翻译 第5章 5.数据模板和样式    
public int MoveNumber 《Programming WPF》翻译 第5章 5.数据模板和样式{
《Programming WPF》翻译 第5章 5.数据模板和样式《Programming WPF》翻译 第5章 5.数据模板和样式      
get 《Programming WPF》翻译 第5章 5.数据模板和样式return moveNumber; }
《Programming WPF》翻译 第5章 5.数据模板和样式《Programming WPF》翻译 第5章 5.数据模板和样式      
set 《Programming WPF》翻译 第5章 5.数据模板和样式{ moveNumber = value; }
《Programming WPF》翻译 第5章 5.数据模板和样式    }

《Programming WPF》翻译 第5章 5.数据模板和样式
《Programming WPF》翻译 第5章 5.数据模板和样式《Programming WPF》翻译 第5章 5.数据模板和样式    
public PlayerMove(string playerName, int moveNumber) 《Programming WPF》翻译 第5章 5.数据模板和样式{
《Programming WPF》翻译 第5章 5.数据模板和样式      
this.playerName = playerName;
《Programming WPF》翻译 第5章 5.数据模板和样式      
this.moveNumber = moveNumber;
《Programming WPF》翻译 第5章 5.数据模板和样式    }

《Programming WPF》翻译 第5章 5.数据模板和样式  }

《Programming WPF》翻译 第5章 5.数据模板和样式}


现在,取代以为每个按钮对象的内容使用一个简单的字符串,我们将用示例

5-20中的一个PlayMover实例鲜明显示这样的一个改动。

示例5-21

 

《Programming WPF》翻译 第5章 5.数据模板和样式《Programming WPF》翻译 第5章 5.数据模板和样式namespace TicTacToe 《Programming WPF》翻译 第5章 5.数据模板和样式{
《Programming WPF》翻译 第5章 5.数据模板和样式《Programming WPF》翻译 第5章 5.数据模板和样式  
public partial class Window1 : Window 《Programming WPF》翻译 第5章 5.数据模板和样式{
《Programming WPF》翻译 第5章 5.数据模板和样式    《Programming WPF》翻译 第5章 5.数据模板和样式
《Programming WPF》翻译 第5章 5.数据模板和样式    
int moveNumber;
《Programming WPF》翻译 第5章 5.数据模板和样式
《Programming WPF》翻译 第5章 5.数据模板和样式《Programming WPF》翻译 第5章 5.数据模板和样式    
void NewGame( ) 《Programming WPF》翻译 第5章 5.数据模板和样式{
《Programming WPF》翻译 第5章 5.数据模板和样式      《Programming WPF》翻译 第5章 5.数据模板和样式
《Programming WPF》翻译 第5章 5.数据模板和样式      
this.moveNumber = 0;
《Programming WPF》翻译 第5章 5.数据模板和样式    }

《Programming WPF》翻译 第5章 5.数据模板和样式
《Programming WPF》翻译 第5章 5.数据模板和样式《Programming WPF》翻译 第5章 5.数据模板和样式    
void cell_Click(object sender, RoutedEventArgs e) 《Programming WPF》翻译 第5章 5.数据模板和样式{
《Programming WPF》翻译 第5章 5.数据模板和样式      《Programming WPF》翻译 第5章 5.数据模板和样式
《Programming WPF》翻译 第5章 5.数据模板和样式      
// Set button content
《Programming WPF》翻译 第5章 5.数据模板和样式      
//button.Content = this.CurrentPlayer;
《Programming WPF》翻译 第5章 5.数据模板和样式
      button.Content =
《Programming WPF》翻译 第5章 5.数据模板和样式        
new PlayerMove(this.CurrentPlayer, ++this.moveNumber);
《Programming WPF》翻译 第5章 5.数据模板和样式      《Programming WPF》翻译 第5章 5.数据模板和样式
《Programming WPF》翻译 第5章 5.数据模板和样式    }

《Programming WPF》翻译 第5章 5.数据模板和样式    《Programming WPF》翻译 第5章 5.数据模板和样式
《Programming WPF》翻译 第5章 5.数据模板和样式  }

《Programming WPF》翻译 第5章 5.数据模板和样式}

5-6
《Programming WPF》翻译 第5章 5.数据模板和样式

正如你回想到的,在第四章,图5-6所发生的是,按钮没有足够多的信息生成一个PlayMover对象,但是我们可以通过一个数据模板修复它。

5.5.1数据模板

回忆第四章,WPF允许你定义一个数据模板,这是一棵元素树,可以在特定的上下文中扩展。数据模板用于提供一个应用程序生成非可视化外观对象的能力,正如示例5-22所示。

示例5-22

《Programming WPF》翻译 第5章 5.数据模板和样式<?Mapping XmlNamespace="l" ClrNamespace="TicTacToe" ?>
《Programming WPF》翻译 第5章 5.数据模板和样式
<Window 《Programming WPF》翻译 第5章 5.数据模板和样式 xmlns:local="local">
《Programming WPF》翻译 第5章 5.数据模板和样式  
<Window.Resources>
《Programming WPF》翻译 第5章 5.数据模板和样式    
<DataTemplate DataType="{x:Type local:PlayerMove}">
《Programming WPF》翻译 第5章 5.数据模板和样式      
<Grid>
《Programming WPF》翻译 第5章 5.数据模板和样式        
<TextBlock
《Programming WPF》翻译 第5章 5.数据模板和样式          
TextContent="{Binding Path=PlayerName}"
《Programming WPF》翻译 第5章 5.数据模板和样式          FontSize 
="32"
《Programming WPF》翻译 第5章 5.数据模板和样式          FontWeight
="Bold"
《Programming WPF》翻译 第5章 5.数据模板和样式          VerticalAlignment
="Center"
《Programming WPF》翻译 第5章 5.数据模板和样式          HorizontalAlignment
="Center" />
《Programming WPF》翻译 第5章 5.数据模板和样式        
<TextBlock
《Programming WPF》翻译 第5章 5.数据模板和样式          
TextContent="{Binding Path=MoveNumber}"
《Programming WPF》翻译 第5章 5.数据模板和样式          FontSize
="16"
《Programming WPF》翻译 第5章 5.数据模板和样式          FontStyle
="Italic"
《Programming WPF》翻译 第5章 5.数据模板和样式          VerticalAlignment
="Bottom"
《Programming WPF》翻译 第5章 5.数据模板和样式          HorizontalAlignment
="Right" />
《Programming WPF》翻译 第5章 5.数据模板和样式      
</Grid>
《Programming WPF》翻译 第5章 5.数据模板和样式    
</DataTemplate>
《Programming WPF》翻译 第5章 5.数据模板和样式    《Programming WPF》翻译 第5章 5.数据模板和样式
《Programming WPF》翻译 第5章 5.数据模板和样式  
</Window.Resources>
《Programming WPF》翻译 第5章 5.数据模板和样式  《Programming WPF》翻译 第5章 5.数据模板和样式
《Programming WPF》翻译 第5章 5.数据模板和样式
</Window>


使用在第一章介绍的

xaml映射语法,我们将PlayMover类型间接映射到了带有xmlns属性的xaml中,我们将其作为数据模板的数据类型。现在,无论何时WPF遇到一个PlayMove对象,如我们所有的按钮内容,数据模板都会展开。在我们这种情形,这个模板由一个grid组成,其中排列了两个TextBlock,一个在按钮中间显示玩家名,另一个在按钮右下位置显示移动的步数,伴随着其它的一些设置使之看起来更漂亮。

5.5.2带样式的数据绑定

尽管如此,这些属性设置深埋在数据模板的很深层。正像这是一个好的想法将“魔力数字”移出你的代码,将它们拉出去并给它们一个易于管理的名称,这是一个好的想法将成组的设置移动到样式中,如示例5-23所示。

*将成组的设置移动到样式中,还顾及皮肤和主题,在第六章会介绍。

示例5-23

《Programming WPF》翻译 第5章 5.数据模板和样式<Window.Resources>
《Programming WPF》翻译 第5章 5.数据模板和样式  
<Style x:Key="CellTextStyle" TargetType="{x:Type TextBlock}">
《Programming WPF》翻译 第5章 5.数据模板和样式    
<Setter Property="FontSize" Value="32" />
《Programming WPF》翻译 第5章 5.数据模板和样式    
<Setter Property="FontWeight" Value="Bold" />
《Programming WPF》翻译 第5章 5.数据模板和样式    
<Setter Property="VerticalAlignment" Value="Center" />
《Programming WPF》翻译 第5章 5.数据模板和样式    
<Setter Property="HorizontalAlignment" Value="Center" />
《Programming WPF》翻译 第5章 5.数据模板和样式  
</Style>
《Programming WPF》翻译 第5章 5.数据模板和样式  
<Style x:Key="MoveNumberStyle" TargetType="{x:Type TextBlock}">
《Programming WPF》翻译 第5章 5.数据模板和样式    
<Setter Property="FontSize" Value="16" />
《Programming WPF》翻译 第5章 5.数据模板和样式    
<Setter Property="FontStyle" Value="Italic" />
《Programming WPF》翻译 第5章 5.数据模板和样式    
<Setter Property="VerticalAlignment" Value="Bottom" />
《Programming WPF》翻译 第5章 5.数据模板和样式    
<Setter Property="HorizontalAlignment" Value="Right" />
《Programming WPF》翻译 第5章 5.数据模板和样式  
</Style>
《Programming WPF》翻译 第5章 5.数据模板和样式  
<DataTemplate DataType="{x:Type l:PlayerMove}">
《Programming WPF》翻译 第5章 5.数据模板和样式    
<Grid>
《Programming WPF》翻译 第5章 5.数据模板和样式      
<TextBlock
《Programming WPF》翻译 第5章 5.数据模板和样式        
TextContent="{Binding Path=PlayerName}"
《Programming WPF》翻译 第5章 5.数据模板和样式        Style
="{StaticResource CellTextStyle}" />
《Programming WPF》翻译 第5章 5.数据模板和样式      
<TextBlock
《Programming WPF》翻译 第5章 5.数据模板和样式        
TextContent="{Binding Path=MoveNumber}"
《Programming WPF》翻译 第5章 5.数据模板和样式        Style
="{StaticResource MoveNumberStyle}" />
《Programming WPF》翻译 第5章 5.数据模板和样式    
</Grid>
《Programming WPF》翻译 第5章 5.数据模板和样式  
</DataTemplate>
《Programming WPF》翻译 第5章 5.数据模板和样式
</Window.Resources>


使用样式是很通常的,从而可以使用数据模板设置成组的属性,创建带有大量属性的大量元素。图

5-7显示了这个结果。

5-7

《Programming WPF》翻译 第5章 5.数据模板和样式

仍然,像图
5-7一样漂亮,交互作用是一种WPF给予的令人厌烦的能力。让我们看一下使用在应用程序中使用样式属性我们都能做些什么。