34章:WPF絵合わせゲームの作成

    作成2013.04.24

     ここでは、Windowsフォームアプリケーション用サンプルコードをWPFアプリケーション用コードに変換します。フォームアプリケーションからWPFアプリケーションへの変化が最近の主流のようです。

  1. 参照元情報
    「絵合わせゲームの作成」にジャンプする
    「0 行でズバリ!! [C#] WPF - Windows フォーム用のコントロールを使う」にジャンプする
     作成方法の詳細は上記を参照願います。


  2. フォームアプリケーションからWPFアプリケーションへの変更
     若干の変更でフォームアプリケーションからWPFアプリケーションへの変更ができます。
     完成ファイルは以下からダウンロードできます。
     ダウンロード後は解凍してから使用してください。
      [絵合わせゲームの作成]をダウンロードする。
     解凍すると「34WpfMatchingGame」フォルダーがあります。
    注(1)「34WpfMatchingGame」フォルダーの「WpfMatchingGame.sln」ファイルをダブルクリックすると「Express 2012 for Windows Desktop」が起動します。
    注(2)メニューの「ウインド」_「ウインドレイアウトのリセット」で標準に戻ります。
    注(3)「ソリューションエクスプローラ」ウインドウ内の「MainWindow.xaml」をダブルクリックすると「デザイン」と「XAML」が表示されます。
    注(4)メニューの「表示」_「コード」を選択するとコードが表示されます。
    注(5)「WpfMatchingGame.sln」の動作確認は「デバッグ」_「デバッグ開始」で実行します。デバッグ機能を用いて動作確認を行います。


  3. WpfMatchingGame.slnの実行
    (1)「Express 2012 for Windows Desktop」のデバッグ機能を使用します。
    (2)「デバッグ」_「デバッグ開始」を選択します。
    (3)全面青の画面が表示されます。
    (4)画面内をクリックすると絵が表示されます。
    (5)続けて画面内の別の位置をクリックすると絵が表示されます。
    (6)この2つの絵が一致すると絵は消えずに残りますが、一致しないと消えます。
    (7)全ての絵が表示されれば完了です。
    (8)クローズボックスでプログラムを終了します。


  4. プロジェクトの構成
    (1)UserControl1.vbの構成
    ・Timer1を配置します。

    (2)XAMLコードの構成
    ・UserControl1を配置します。
    ・Labelを配置します。

    注:Timer1がフォームアプリケーション用のツールとなります。


  5. MainWindow.xamlの全コード
    <Window x:Class="WpfMatchingGame.MainWindow"	
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"	
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"	
            xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms" 	
        xmlns:self="clr-namespace:WpfMatchingGame" 	
        Title="MainWindow" Height="550" Width="550">	
        <Grid Background="CornflowerBlue" Name="Grid1">	
            <Grid.RowDefinitions>	
                <RowDefinition Height="*" />	
                <RowDefinition Height="*" />	
                <RowDefinition Height="*" />	
                <RowDefinition Height="*" />	
            </Grid.RowDefinitions>	
            <Grid.ColumnDefinitions>	
                <ColumnDefinition Width="*" />	
                <ColumnDefinition Width="*" />	
                <ColumnDefinition Width="*" />	
                <ColumnDefinition Width="*" />	
            </Grid.ColumnDefinitions>	
            <WindowsFormsHost Visibility="Hidden">	
                <self:UserControl1 x:Name="myControl"/>	
            </WindowsFormsHost>	
    	
            <Label Content="c"  HorizontalAlignment="Center"  Name="Label1" VerticalAlignment="Center" Height="127" Width="132" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Background="CornflowerBlue" FontFamily="Webdings" FontSize="72" FontWeight="Bold" MouseDown="Label_MouseDown" />	
            <Label Background="CornflowerBlue" Content="c" FontFamily="Webdings" FontSize="72" FontWeight="Bold" Height="127" HorizontalAlignment="Center" HorizontalContentAlignment="Center" Margin="0,0,0,1" Name="Label2" VerticalAlignment="Center" VerticalContentAlignment="Center" Width="132" Grid.Column="1" MouseDown="Label_MouseDown"/>	
            <Label Background="CornflowerBlue" Content="c" FontFamily="Webdings" FontSize="72" FontWeight="Bold" Height="127" HorizontalAlignment="Center" HorizontalContentAlignment="Center" Margin="0,0,0,1" Name="Label3" VerticalAlignment="Center" VerticalContentAlignment="Center" Width="132" Grid.Column="2" MouseDown="Label_MouseDown"/>	
            <Label Background="CornflowerBlue" Content="c" FontFamily="Webdings" FontSize="72" FontWeight="Bold" Height="127" HorizontalAlignment="Center" HorizontalContentAlignment="Center" Margin="0,1,0,0" Name="Label4" VerticalAlignment="Center" VerticalContentAlignment="Center" Width="132" Grid.Column="3" MouseDown="Label_MouseDown"/>	
            <Label Background="CornflowerBlue" Content="c" FontFamily="Webdings" FontSize="72" FontWeight="Bold" Height="127" HorizontalAlignment="Center" HorizontalContentAlignment="Center" Name="Label5" VerticalAlignment="Center" VerticalContentAlignment="Center" Width="132" Grid.Row="1" MouseDown="Label_MouseDown"/>	
            <Label Background="CornflowerBlue" Content="c" FontFamily="Webdings" FontSize="72" FontWeight="Bold" Height="127" HorizontalAlignment="Center" HorizontalContentAlignment="Center" Name="Label6" VerticalAlignment="Center" VerticalContentAlignment="Center" Width="132" Grid.Column="1" Grid.Row="1"  MouseDown="Label_MouseDown" />	
            <Label Background="CornflowerBlue" Content="c" FontFamily="Webdings" FontSize="72" FontWeight="Bold" Height="127" HorizontalAlignment="Center" HorizontalContentAlignment="Center" Margin="0,0,0,1" Name="Label7" VerticalAlignment="Center" VerticalContentAlignment="Center" Width="132" Grid.Column="2" Grid.Row="1" MouseDown="Label_MouseDown" />	
            <Label Background="CornflowerBlue" Content="c" FontFamily="Webdings" FontSize="72" FontWeight="Bold" Height="127" HorizontalAlignment="Center" HorizontalContentAlignment="Center" Name="Label8" VerticalAlignment="Center" VerticalContentAlignment="Center" Width="132" Grid.Column="3" Grid.Row="1" MouseDown="Label_MouseDown"/>	
            <Label Background="CornflowerBlue" Content="c" FontFamily="Webdings" FontSize="72" FontWeight="Bold" Height="127" HorizontalAlignment="Center" HorizontalContentAlignment="Center" Name="Label9" VerticalAlignment="Center" VerticalContentAlignment="Center" Width="132" Grid.Row="2" MouseDown="Label_MouseDown"/>	
            <Label Background="CornflowerBlue" Content="c" FontFamily="Webdings" FontSize="72" FontWeight="Bold" Height="127" HorizontalAlignment="Center" HorizontalContentAlignment="Center" Name="Label10" VerticalAlignment="Center" VerticalContentAlignment="Center" Width="132" Grid.Column="1" Grid.Row="2" MouseDown="Label_MouseDown"/>	
            <Label Background="CornflowerBlue" Content="c" FontFamily="Webdings" FontSize="72" FontWeight="Bold" Height="127" HorizontalAlignment="Center" HorizontalContentAlignment="Center" Name="Label11" VerticalAlignment="Center" VerticalContentAlignment="Center" Width="132" Grid.Column="2" Grid.Row="2" MouseDown="Label_MouseDown"/>	
            <Label Background="CornflowerBlue" Content="c" FontFamily="Webdings" FontSize="72" FontWeight="Bold" Height="127" HorizontalAlignment="Center" HorizontalContentAlignment="Center" Name="Label12" VerticalAlignment="Center" VerticalContentAlignment="Center" Width="132" Grid.Column="3" Grid.Row="2" MouseDown="Label_MouseDown"/>	
            <Label Background="CornflowerBlue" Content="c" FontFamily="Webdings" FontSize="72" FontWeight="Bold" Height="127" HorizontalAlignment="Center" HorizontalContentAlignment="Center" Name="Label13" VerticalAlignment="Center" VerticalContentAlignment="Center" Width="132" Grid.Row="3" MouseDown="Label_MouseDown"/>	
            <Label Background="CornflowerBlue" Content="c" FontFamily="Webdings" FontSize="72" FontWeight="Bold" Height="127" HorizontalAlignment="Center" HorizontalContentAlignment="Center" Name="Label14" VerticalAlignment="Center" VerticalContentAlignment="Center" Width="132" Grid.Column="1" Grid.Row="3" MouseDown="Label_MouseDown"/>	
            <Label Background="CornflowerBlue" Content="c" FontFamily="Webdings" FontSize="72" FontWeight="Bold" Height="127" HorizontalAlignment="Center" HorizontalContentAlignment="Center" Name="Label15" VerticalAlignment="Center" VerticalContentAlignment="Center" Width="132" Grid.Column="2" Grid.Row="3" MouseDown="Label_MouseDown"/>	
            <Label Background="CornflowerBlue" Content="c" FontFamily="Webdings" FontSize="72" FontWeight="Bold" Height="127" HorizontalAlignment="Center" HorizontalContentAlignment="Center" Name="Label16" VerticalAlignment="Center" VerticalContentAlignment="Center" Width="132" Grid.Column="3" Grid.Row="3" MouseDown="Label_MouseDown"/>		
        </Grid>	
    </Window>			
    


  6. MainWindow.xamlコードの解説
    (1)<Window>階層1:クラス:以下の記載が特別です。
     xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
     上記の記載はUserControlを使用するための記載です。
     xmlns:self="clr-namespace:WpfMatchingGame"
     上記の記載はWpfMatchingGameソリューションを使用するための記載です。
    (2) <WindowsFormsHost x:Name="wfHost" Grid.Row="0">
    <self:UserControl1 x:Name="myControl" />
    </WindowsFormsHost>
     上記の記載でUserControl1の使用条件を設定します。名前は"myControl" となります。
    (3)Grid機能を使用してLabelを配置します。


  7. MainWindow.xaml.csの全コード
    using System;
    using System.Collections.Generic;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Input;
    using System.Windows.Media;
    
    namespace WpfMatchingGame
    {
        public partial class MainWindow : Window
        {
            Random random = new Random();
            List icons = new List() { "!", "!", "N", "N", ",", ",", "k", "k", "b", "b", "v", "v", "w", "w", "z", "z" };
            Label firstClicked = null;
            Label secondClicked = null;
    
            public MainWindow()
            {
                InitializeComponent();
                AssignIconsToSquares();
                myControl.UC = this;
            }
    
            private void AssignIconsToSquares()
            {
                foreach (var control in this.Grid1.Children)
                {
                    Label iconLabel = control as Label;
                    if (iconLabel != null)
                    {
                        int randomNumber = random.Next(icons.Count);
                        iconLabel.Content = icons[randomNumber];
                        iconLabel.Foreground = iconLabel.Background;
                        icons.RemoveAt(randomNumber);
                    }
                }
            }
    
            public void Timer_Tick(object sender, EventArgs e)
            {
                myControl.Timer1.Stop();
                firstClicked.Foreground = firstClicked.Background;
                secondClicked.Foreground = secondClicked.Background;
                firstClicked = null;
                secondClicked = null;
            }
    
            private void Label_MouseDown(object sender, MouseButtonEventArgs e)
            {
                if (myControl.Timer1.Enabled == true) return;
                Label clickedLabel = sender as Label;
    
                SolidColorBrush Br = new SolidColorBrush();
                 Br.Color = Color.FromRgb(0, 0, 0);
    
                if (clickedLabel != null)
                {
                    if (clickedLabel.Foreground.Equals(Color.FromRgb(0, 0, 0))) return;
                    if (firstClicked == null)
                    {
                        firstClicked = clickedLabel;
                        firstClicked.Foreground = Br;
                        return;
                    }
                    secondClicked = clickedLabel;
                    secondClicked.Foreground = Br;
                    CheckForWinner();
                    if (firstClicked.Content == secondClicked.Content)
                    {
                        firstClicked = null;
                        secondClicked = null;
                        return;
                    }
                    myControl.Timer1.Start();
                }
    
            }
    
            private void CheckForWinner()
            {
                foreach (var control in this.Grid1.Children)
                {
                    Label iconLabel = control as Label;
                    if (iconLabel != null)
                    {
                        if (iconLabel.Foreground.Equals(iconLabel.Background)) return;
                    }
                }
                MessageBox.Show("You matched all the icons!", "Congratulations");
                Close();
            }
        }
    }
    


  8. MainWindow.xaml.csコードの解説
    (1)myControl.UC = Meは特別なコードです。UserControl1クラスで Public UC As MainWindowとし、変数UCをMainWindow型で生成します。
      MeはMainWindowの実体であり、UserControl1クラスにMainWindowの実体を渡します。
    (2) Public Sub Timer_TickはUserControl1クラスから呼び出されます。


  9. Public Class UserControl1クラスのコード
    using System;
    using System.Windows.Forms;
    
    namespace WpfMatchingGame
    {
        public partial class UserControl1 : UserControl
        {
            public MainWindow UC;
            public UserControl1()
            {
                InitializeComponent();
            }
    
            private void Timer1_Tick(object sender, EventArgs e)
            {
                UC.Timer_Tick(sender, e);
            }
        }
    }
    


  10. Public Class UserControl1クラスのコード解説
    (1)Private Sub Timer1_Tickは自動的にUserControl1クラスに設定されます。
    (2)主要コードはMainWindowクラスに集中させる都合上、MainWindowクラスのTimer_Tickを呼び出す必要があります。


    感想:
    (1)VBとC#そしてフォームアプリケーションとWPFアプリリケーションで微妙にコードの記述が異なります。
    (2)微妙なコードの記述の違いでけっこう混乱します。







35章:WPFクラスを使用するに行く。

トップページに戻る。