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

简介: 原文:《Programming WPF》翻译 第5章 1.不使用样式作为一个样式如何使其在WPF使用的例子,,让我们看一下TTT简单的实现,如示例5-1。 示例5-1                                                                                                  这个grid的外观上排列了一组9个按钮在一个3X3栅格的TTT单元中,在按钮上使用了页面空白为了TTT的交叉线阴影。
原文: 《Programming WPF》翻译 第5章 1.不使用样式

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

示例5-1

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


这个

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

示例5-2

 

//  Window1.xaml.cs

namespace  TicTacToe  {
  
public partial class Window1 : Window {
    
// Track the current player (X or O)
    string currentPlayer;

    
// Track the list of cells for finding a winner etc.
    Button[] cells;

    
public Window1( ) {
      InitializeComponent( );

      
// Cache the list of buttons and handle their clicks
      this.cells = new Button[] this.cell00, this.cell01,  };
      
foreach( Button cell in this.cells ) {
        cell.Click 
+= cell_Click;
      }


      
// Initialize a new game
      NewGame( );
    }


    
// Wrapper around the current player for future expansion,
    
// e.g. updating status text with the current player
    string CurrentPlayer {
      
get return this.currentPlayer; }
      
set this.currentPlayer = value; }
    }


    
// Use the buttons to track game state
    void NewGame( ) {

      
foreach( Button cell in this.cells ) {
        cell.Content 
= null;
      }

      CurrentPlayer 
= "X";
    }


    
void cell_Click(object sender, RoutedEventArgs e) {
      Button button 
= (Button)sender;

      
// Don't let multiple clicks change the player for a cell
      if( button.Content != null ) return; }


      
// Set button content
      button.Content = CurrentPlayer;

      
// Check for winner or a tie
      if( HasWon(this.currentPlayer) ) {
        MessageBox.Show(
"Winner!""Game Over");
        NewGame( );
        
return;
      }

      
else if( TieGame( ) ) {
        MessageBox.Show(
"No Winner!""Game Over");
        NewGame( );
        
return;
      }



      
// Switch player
      if( CurrentPlayer == "X" ) {
        CurrentPlayer 
= "O";
      }

      
else {
        CurrentPlayer 
= "X";
      }

    }


    
// Use this.cells to find a winner or a tie
    bool HasWon(string player) {}
    
bool TieGame( ) {}
  }

}


我们的简单

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

5-1



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

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

示例5-3

< Button  FontSize ="32"  FontWeight ="Bold"   x:Name ="cell00"   />
< Button  FontSize ="32"  FontWeight ="Bold"  x:Name ="cell01"   />
< Button  FontSize ="32"  FontWeight ="Bold"  x:Name ="cell02"   />
< Button  FontSize ="32"  FontWeight ="Bold"  x:Name ="cell10"   />
< Button  FontSize ="32"  FontWeight ="Bold"  x:Name ="cell11"   />
< Button  FontSize ="32"  FontWeight ="Bold"  x:Name ="cell12"   />
< Button  FontSize ="32"  FontWeight ="Bold"  x:Name ="cell20"   />
< Button  FontSize ="32"  FontWeight ="Bold"  x:Name ="cell21"   />
< Button  FontSize ="32"  FontWeight ="Bold"  x:Name ="cell22"   />

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

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

目录
相关文章
|
8月前
|
C#
WPF疑难问题之Treeview中HierarchicalDataTemplate多级样式
WPF疑难问题之Treeview中HierarchicalDataTemplate多级样式
148 0
|
1月前
|
文字识别 C# 开发者
WPF开源的一款免费、开箱即用的翻译、OCR工具
WPF开源的一款免费、开箱即用的翻译、OCR工具
|
2月前
|
C#
浅谈WPF之样式与资源
WPF通过样式,不仅可以方便的设置控件元素的展示方式,给用户呈现多样化的体验,还简化配置,避免重复设置元素的属性,以达到节约成本,提高工作效率的目的,样式也是资源的一种表现形式。本文以一个简单的小例子,简述如何设置WPF的样式以及资源的应用,仅供学习分享使用,如有不足之处,还请指正。
42 0
|
8月前
WPF-布局样式练习-Day02-聊天气泡
WPF-布局样式练习-Day02-聊天气泡
129 1
|
8月前
|
C#
WPF-Binding问题-模板样式使用Binding TemplatedParent与TemplateBinding区别
WPF-Binding问题-模板样式使用Binding TemplatedParent与TemplateBinding区别
82 0
|
8月前
WPF-样式问题-处理ListBox、ListView子项内容全填充问题
WPF-样式问题-处理ListBox、ListView子项内容全填充问题
114 0
|
8月前
|
C#
WPF-布局样式练习-Day01
WPF-布局样式练习-Day01
71 0
|
8月前
WPF-样式问题-ListBox或ListView中子项全填充去除边线问题
WPF-样式问题-ListBox或ListView中子项全填充去除边线问题
72 0
|
9月前
|
C#
WPF属性---重复样式和触发器
WPF属性---重复样式和触发器
70 0
|
前端开发 C#
wpf引用样式
wpf引用样式
93 0