且构网

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

《Programming WPF》翻译 第5章 1.不使用样式

更新时间:2022-09-18 12:33:50

原文:《Programming WPF》翻译 第5章 1.不使用样式

作为一个样式如何使其在WPF使用的例子,,让我们看一下TTT简单的实现,如示例5-1

示例5-1

《Programming WPF》翻译 第5章 1.不使用样式<!-- Window1.xaml -->
《Programming WPF》翻译 第5章 1.不使用样式
<Window
《Programming WPF》翻译 第5章 1.不使用样式    
x:Class="TicTacToe.Window1"
《Programming WPF》翻译 第5章 1.不使用样式    xmlns
="http://schemas.microsoft.com/winfx/avalon/2005"
《Programming WPF》翻译 第5章 1.不使用样式    xmlns:x
="http://schemas.microsoft.com/winfx/xaml/2005"
《Programming WPF》翻译 第5章 1.不使用样式    Text
="TicTacToe">
《Programming WPF》翻译 第5章 1.不使用样式  
<!-- the black background lets the tic-tac-toe -->
《Programming WPF》翻译 第5章 1.不使用样式  
<!-- crosshatch come through on the margins -->
《Programming WPF》翻译 第5章 1.不使用样式  
<Grid Background="Black">
《Programming WPF》翻译 第5章 1.不使用样式    
<Grid.RowDefinitions>
《Programming WPF》翻译 第5章 1.不使用样式      
<RowDefinition />
《Programming WPF》翻译 第5章 1.不使用样式      
<RowDefinition />
《Programming WPF》翻译 第5章 1.不使用样式      
<RowDefinition />
《Programming WPF》翻译 第5章 1.不使用样式    
</Grid.RowDefinitions>
《Programming WPF》翻译 第5章 1.不使用样式    
<Grid.ColumnDefinitions>
《Programming WPF》翻译 第5章 1.不使用样式      
<ColumnDefinition />
《Programming WPF》翻译 第5章 1.不使用样式      
<ColumnDefinition />
《Programming WPF》翻译 第5章 1.不使用样式      
<ColumnDefinition />
《Programming WPF》翻译 第5章 1.不使用样式    
</Grid.ColumnDefinitions>
《Programming WPF》翻译 第5章 1.不使用样式    
<Button Margin="0,0,2,2" Grid.Row="0" Grid.Column="0" x:Name="cell00" />
《Programming WPF》翻译 第5章 1.不使用样式    
<Button Margin="2,0,2,2" Grid.Row="0" Grid.Column="1" x:Name="cell01" />
《Programming WPF》翻译 第5章 1.不使用样式    
<Button Margin="2,0,0,2" Grid.Row="0" Grid.Column="2" x:Name="cell02" />
《Programming WPF》翻译 第5章 1.不使用样式    
<Button Margin="0,2,2,2" Grid.Row="1" Grid.Column="0" x:Name="cell10" />
《Programming WPF》翻译 第5章 1.不使用样式    
<Button Margin="2,2,2,2" Grid.Row="1" Grid.Column="1" x:Name="cell11" />
《Programming WPF》翻译 第5章 1.不使用样式    
<Button Margin="2,2,0,2" Grid.Row="1" Grid.Column="2" x:Name="cell12" />
《Programming WPF》翻译 第5章 1.不使用样式    
<Button Margin="0,2,2,0" Grid.Row="2" Grid.Column="0" x:Name="cell20" />
《Programming WPF》翻译 第5章 1.不使用样式    
<Button Margin="2,2,2,0" Grid.Row="2" Grid.Column="1" x:Name="cell21" />
《Programming WPF》翻译 第5章 1.不使用样式    
<Button Margin="2,2,0,0" Grid.Row="2" Grid.Column="2" x:Name="cell22" />
《Programming WPF》翻译 第5章 1.不使用样式  
</Grid>
《Programming WPF》翻译 第5章 1.不使用样式
</Window>


这个

grid的外观上排列了一组9个按钮在一个3X3栅格的TTT单元中,在按钮上使用了页面空白为了TTT的交叉线阴影。对游戏逻辑的一个简单的实现,在xaml后台代码中,如示例5-2所示。

示例5-2

 

《Programming WPF》翻译 第5章 1.不使用样式// Window1.xaml.cs
《Programming WPF》翻译 第5章 1.不使用样式
《Programming WPF》翻译 第5章 1.不使用样式
《Programming WPF》翻译 第5章 1.不使用样式《Programming WPF》翻译 第5章 1.不使用样式
namespace TicTacToe 《Programming WPF》翻译 第5章 1.不使用样式{
《Programming WPF》翻译 第5章 1.不使用样式《Programming WPF》翻译 第5章 1.不使用样式  
public partial class Window1 : Window 《Programming WPF》翻译 第5章 1.不使用样式{
《Programming WPF》翻译 第5章 1.不使用样式    
// Track the current player (X or O)
《Programming WPF》翻译 第5章 1.不使用样式
    string currentPlayer;
《Programming WPF》翻译 第5章 1.不使用样式
《Programming WPF》翻译 第5章 1.不使用样式    
// Track the list of cells for finding a winner etc.
《Programming WPF》翻译 第5章 1.不使用样式
    Button[] cells;
《Programming WPF》翻译 第5章 1.不使用样式
《Programming WPF》翻译 第5章 1.不使用样式《Programming WPF》翻译 第5章 1.不使用样式    
public Window1( ) 《Programming WPF》翻译 第5章 1.不使用样式{
《Programming WPF》翻译 第5章 1.不使用样式      InitializeComponent( );
《Programming WPF》翻译 第5章 1.不使用样式
《Programming WPF》翻译 第5章 1.不使用样式      
// Cache the list of buttons and handle their clicks
《Programming WPF》翻译 第5章 1.不使用样式《Programming WPF》翻译 第5章 1.不使用样式
      this.cells = new Button[] 《Programming WPF》翻译 第5章 1.不使用样式this.cell00, this.cell01, 《Programming WPF》翻译 第5章 1.不使用样式 };
《Programming WPF》翻译 第5章 1.不使用样式《Programming WPF》翻译 第5章 1.不使用样式      
foreach( Button cell in this.cells ) 《Programming WPF》翻译 第5章 1.不使用样式{
《Programming WPF》翻译 第5章 1.不使用样式        cell.Click 
+= cell_Click;
《Programming WPF》翻译 第5章 1.不使用样式      }

《Programming WPF》翻译 第5章 1.不使用样式
《Programming WPF》翻译 第5章 1.不使用样式      
// Initialize a new game
《Programming WPF》翻译 第5章 1.不使用样式
      NewGame( );
《Programming WPF》翻译 第5章 1.不使用样式    }

《Programming WPF》翻译 第5章 1.不使用样式
《Programming WPF》翻译 第5章 1.不使用样式    
// Wrapper around the current player for future expansion,
《Programming WPF》翻译 第5章 1.不使用样式    
// e.g. updating status text with the current player
《Programming WPF》翻译 第5章 1.不使用样式《Programming WPF》翻译 第5章 1.不使用样式
    string CurrentPlayer 《Programming WPF》翻译 第5章 1.不使用样式{
《Programming WPF》翻译 第5章 1.不使用样式《Programming WPF》翻译 第5章 1.不使用样式      
get 《Programming WPF》翻译 第5章 1.不使用样式return this.currentPlayer; }
《Programming WPF》翻译 第5章 1.不使用样式《Programming WPF》翻译 第5章 1.不使用样式      
set 《Programming WPF》翻译 第5章 1.不使用样式this.currentPlayer = value; }
《Programming WPF》翻译 第5章 1.不使用样式    }

《Programming WPF》翻译 第5章 1.不使用样式
《Programming WPF》翻译 第5章 1.不使用样式    
// Use the buttons to track game state
《Programming WPF》翻译 第5章 1.不使用样式《Programming WPF》翻译 第5章 1.不使用样式
    void NewGame( ) 《Programming WPF》翻译 第5章 1.不使用样式{
《Programming WPF》翻译 第5章 1.不使用样式
《Programming WPF》翻译 第5章 1.不使用样式《Programming WPF》翻译 第5章 1.不使用样式      
foreach( Button cell in this.cells ) 《Programming WPF》翻译 第5章 1.不使用样式{
《Programming WPF》翻译 第5章 1.不使用样式        cell.Content 
= null;
《Programming WPF》翻译 第5章 1.不使用样式      }

《Programming WPF》翻译 第5章 1.不使用样式      CurrentPlayer 
= "X";
《Programming WPF》翻译 第5章 1.不使用样式    }

《Programming WPF》翻译 第5章 1.不使用样式
《Programming WPF》翻译 第5章 1.不使用样式《Programming WPF》翻译 第5章 1.不使用样式    
void cell_Click(object sender, RoutedEventArgs e) 《Programming WPF》翻译 第5章 1.不使用样式{
《Programming WPF》翻译 第5章 1.不使用样式      Button button 
= (Button)sender;
《Programming WPF》翻译 第5章 1.不使用样式
《Programming WPF》翻译 第5章 1.不使用样式      
// Don't let multiple clicks change the player for a cell
《Programming WPF》翻译 第5章 1.不使用样式《Programming WPF》翻译 第5章 1.不使用样式
      if( button.Content != null ) 《Programming WPF》翻译 第5章 1.不使用样式return; }
《Programming WPF》翻译 第5章 1.不使用样式
《Programming WPF》翻译 第5章 1.不使用样式
《Programming WPF》翻译 第5章 1.不使用样式      
// Set button content
《Programming WPF》翻译 第5章 1.不使用样式
      button.Content = CurrentPlayer;
《Programming WPF》翻译 第5章 1.不使用样式
《Programming WPF》翻译 第5章 1.不使用样式      
// Check for winner or a tie
《Programming WPF》翻译 第5章 1.不使用样式《Programming WPF》翻译 第5章 1.不使用样式
      if( HasWon(this.currentPlayer) ) 《Programming WPF》翻译 第5章 1.不使用样式{
《Programming WPF》翻译 第5章 1.不使用样式        MessageBox.Show(
"Winner!""Game Over");
《Programming WPF》翻译 第5章 1.不使用样式        NewGame( );
《Programming WPF》翻译 第5章 1.不使用样式        
return;
《Programming WPF》翻译 第5章 1.不使用样式      }

《Programming WPF》翻译 第5章 1.不使用样式《Programming WPF》翻译 第5章 1.不使用样式      
else if( TieGame( ) ) 《Programming WPF》翻译 第5章 1.不使用样式{
《Programming WPF》翻译 第5章 1.不使用样式        MessageBox.Show(
"No Winner!""Game Over");
《Programming WPF》翻译 第5章 1.不使用样式        NewGame( );
《Programming WPF》翻译 第5章 1.不使用样式        
return;
《Programming WPF》翻译 第5章 1.不使用样式      }

《Programming WPF》翻译 第5章 1.不使用样式
《Programming WPF》翻译 第5章 1.不使用样式
《Programming WPF》翻译 第5章 1.不使用样式      
// Switch player
《Programming WPF》翻译 第5章 1.不使用样式《Programming WPF》翻译 第5章 1.不使用样式
      if( CurrentPlayer == "X" ) 《Programming WPF》翻译 第5章 1.不使用样式{
《Programming WPF》翻译 第5章 1.不使用样式        CurrentPlayer 
= "O";
《Programming WPF》翻译 第5章 1.不使用样式      }

《Programming WPF》翻译 第5章 1.不使用样式《Programming WPF》翻译 第5章 1.不使用样式      
else 《Programming WPF》翻译 第5章 1.不使用样式{
《Programming WPF》翻译 第5章 1.不使用样式        CurrentPlayer 
= "X";
《Programming WPF》翻译 第5章 1.不使用样式      }

《Programming WPF》翻译 第5章 1.不使用样式    }

《Programming WPF》翻译 第5章 1.不使用样式
《Programming WPF》翻译 第5章 1.不使用样式    
// Use this.cells to find a winner or a tie
《Programming WPF》翻译 第5章 1.不使用样式《Programming WPF》翻译 第5章 1.不使用样式
    bool HasWon(string player) 《Programming WPF》翻译 第5章 1.不使用样式{《Programming WPF》翻译 第5章 1.不使用样式}
《Programming WPF》翻译 第5章 1.不使用样式《Programming WPF》翻译 第5章 1.不使用样式    
bool TieGame( ) 《Programming WPF》翻译 第5章 1.不使用样式{《Programming WPF》翻译 第5章 1.不使用样式}
《Programming WPF》翻译 第5章 1.不使用样式  }

《Programming WPF》翻译 第5章 1.不使用样式}


我们的简单

TTT逻辑使用字符串代表玩家,使用按钮来跟踪游戏状态。当点击任意一个按钮时,我们将内容设置为字符串,用来象征当前玩家以及转换玩家。当游戏结束的时候,每一个按钮上的内容都会被清除。游戏中的截图如图5-1

5-1

《Programming WPF》翻译 第5章 1.不使用样式

注意到图
5-1中,grid的背景来自页面的空白。这些空白差不多使grid看上去像一个可绘制的TTT木板(虽然我们将来会做的更好)。然而,如果我们真的指望模仿一个手绘的游戏,我们已经对按钮上的字体大小做了设置,但并没匹配到线条的厚度。

一种修复这个问题的方法是为每一个按钮对象设置字体和宽度,如示例5-3

示例5-3

《Programming WPF》翻译 第5章 1.不使用样式<Button FontSize="32" FontWeight="Bold" 《Programming WPF》翻译 第5章 1.不使用样式 x:Name="cell00" />
《Programming WPF》翻译 第5章 1.不使用样式
<Button FontSize="32" FontWeight="Bold"《Programming WPF》翻译 第5章 1.不使用样式 x:Name="cell01" />
《Programming WPF》翻译 第5章 1.不使用样式
<Button FontSize="32" FontWeight="Bold"《Programming WPF》翻译 第5章 1.不使用样式 x:Name="cell02" />
《Programming WPF》翻译 第5章 1.不使用样式
<Button FontSize="32" FontWeight="Bold"《Programming WPF》翻译 第5章 1.不使用样式 x:Name="cell10" />
《Programming WPF》翻译 第5章 1.不使用样式
<Button FontSize="32" FontWeight="Bold"《Programming WPF》翻译 第5章 1.不使用样式 x:Name="cell11" />
《Programming WPF》翻译 第5章 1.不使用样式
<Button FontSize="32" FontWeight="Bold"《Programming WPF》翻译 第5章 1.不使用样式 x:Name="cell12" />
《Programming WPF》翻译 第5章 1.不使用样式
<Button FontSize="32" FontWeight="Bold"《Programming WPF》翻译 第5章 1.不使用样式 x:Name="cell20" />
《Programming WPF》翻译 第5章 1.不使用样式
<Button FontSize="32" FontWeight="Bold"《Programming WPF》翻译 第5章 1.不使用样式 x:Name="cell21" />
《Programming WPF》翻译 第5章 1.不使用样式
<Button FontSize="32" FontWeight="Bold"《Programming WPF》翻译 第5章 1.不使用样式 x:Name="cell22" />

依照我的视觉敏感性,今天,虽然这样做使得

X的和O的外观更好,一旦我以后想改动它,我就要负责在9个独立的地方改变这些属性,这是重复性的努力——违反了我的编码敏感性。我宁愿重制我的决定——为了以后的维护,将我的TTT单元的外观放在一个共同的地方。这是样式派得上用场的地方。