Sunday, February 28, 2010

Shatranj - Convert to Control (1 of 3): Need for ControlTemplates

Let’s revisit our requirements:

  1. When it’s a player’s turn (playing White/Black), the player should only be able to select one of his/her piece for making the move
  2. This also applies to the opponent
  3. When any of the empty squares are captured by either players, that square is owned by the piece occupying it.

Hmm…  The BoardSquareView is a UserControl!  It doesn’t support Mouse events directly for one.  How good it would be, if it were a button!  No, wait!  Yes, it should be a RadioButton.

WPF lets RadioButtons grouped through the GroupName property.  In the absence of Blend, I’ll have to make do with manually editing XAML to do this.  Just search for UserControl and replace it with RadioButton:

    1 <RadioButton x:Class="Shatranj.BoardSquareView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    2             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Shatranj="clr-namespace:Shatranj"

    3             Background="{Binding Converter={StaticResource LocationToColorConverter}}">

    4 

    5     <RadioButton.Resources>

    6         <Style TargetType="{x:Type Shatranj:BoardSquareView}">

    7             <Style.Triggers>

    8                 <Trigger Property="IsMouseOver" Value="true">

    9                     <Setter Property="Foreground" Value="Red" />

   10                     <Setter Property="Background" Value="Black" />

   11                     <Setter Property="BorderBrush" Value="Red" />

   12                     <Setter Property="BorderThickness" Value="2" />

   13                 </Trigger>

   14             </Style.Triggers>

   15         </Style>

   16         <Shatranj:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />

   17     </RadioButton.Resources>

   18 

   19     <ContentPresenter>

   20         <ContentPresenter.Content>

   21             <Grid>

   22                 <Grid.RowDefinitions>

   23                     <RowDefinition Height="0.200*" />

   24                     <RowDefinition Height="0.800*" />

   25                 </Grid.RowDefinitions>

   26                 <Grid.ColumnDefinitions>

   27                     <ColumnDefinition />

   28                 </Grid.ColumnDefinitions>

   29 

   30                 <Viewbox Grid.Row="0" Grid.Column="0" HorizontalAlignment="Right" VerticalAlignment="Stretch">

   31                     <TextBlock FontSize="12" FontFamily="Consolas" Text="{Binding Path=AlgebraicIdentity, Mode=OneWay}" />

   32                 </Viewbox>

   33                 <Viewbox Grid.RowSpan="2" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center">

   34                     <TextBlock FontFamily="Chess Cases"

   35                               Margin="3,3,3,3"

   36                               Text="{Binding Path=CurrentPiece.AltChar, Mode=OneWay}" />

   37                 </Viewbox>

   38 

   39                 <Ellipse MaxHeight="30" MaxWidth="30"

   40                         MinHeight="10"

   41                         MinWidth="10" Fill="Aqua"

   42                         Grid.Row="0" Grid.RowSpan="2"

   43                         Visibility="{Binding IsHit, Converter={StaticResource BoolToVisibilityConverter}}" />

   44             </Grid>

   45         </ContentPresenter.Content>

   46     </ContentPresenter>

   47 </RadioButton>

 

Oops…. The results are not encouraging.  We still got the RadioButton’s default UI interfering.  This is a useful behavior when we want to layer multiple levels of controls using inheritance.  At the moment, we need something more heavyweight.  Enter ControlTemplates!

 

UC2RB

No comments: