32章:チュートリアル31:WPF絵合わせゲームの作成

    作成2013.04.03

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

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


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


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


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

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

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


  5. XAMLの全コード
    <Window x:Class="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" />
            <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" />
            <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" />
            <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" />
            <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" />
            <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" />
            <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" />
            <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" />
            <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" />
            <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" />
            <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" />
            <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" />
            <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" />
            <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" />
            <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" />
            <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" />
            
        </Grid>
    </Window>
    


  6. 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. Class MainWindowクラスの全コード
    Class MainWindow 
        Dim random As New Random
        Dim temporaryArray() As String = {"!", "!", "N", "N", ",", ",", "k", "k", "b", "b", "v", "v", "w", "w", "z", "z"}
        Dim icons As List(Of String) = temporaryArray.ToList
        Dim firstClicked As Label = Nothing
        Dim secondClicked As Label = Nothing
    
        Public Sub New()
            InitializeComponent()
            InitializeComponent()
            AssignIconsToSquares()
            myControl.UC = Me
        End Sub
    
        Private Sub AssignIconsToSquares()
            For Each control In Grid1.Children
                Dim iconLabel As Label = TryCast(control, Label)
                If iconLabel IsNot Nothing Then
                    Dim randomNumber As Integer = random.Next(icons.Count)
                    iconLabel.Content = icons.ElementAt(randomNumber)
                    iconLabel.Foreground = iconLabel.Background
                    icons.RemoveAt(randomNumber)
                End If
            Next
        End Sub
    
        Private Sub CheckForWinner()
            For Each control In Grid1.Children
                Dim iconLabel As Label = TryCast(control, Label)
                If iconLabel IsNot Nothing Then
                    If (iconLabel.Foreground.Equals(iconLabel.Background)) Then
                        Return
                    End If
                End If
            Next
            MessageBox.Show("You matched all the icons!", "Congratulations")
            Close()
        End Sub
    
        Private Sub Label16_MouseDown(sender As System.Object, e As System.Windows.Input.MouseButtonEventArgs) Handles Label16.MouseDown, Label15.MouseDown, Label14.MouseDown, Label13.MouseDown, Label12.MouseDown, Label11.MouseDown, Label10.MouseDown, Label9.MouseDown, Label8.MouseDown, Label7.MouseDown, Label6.MouseDown, Label5.MouseDown, Label4.MouseDown, Label3.MouseDown, Label2.MouseDown, Label1.MouseDown
            If (myControl.Timer1.Enabled = True) Then
                Return
            End If
    
            Dim Br As New Windows.Media.SolidColorBrush
            Br.Color = Color.FromRgb(0, 0, 0)
    
    
            Dim clickedLabel As Label = TryCast(sender, Label)
            If clickedLabel IsNot Nothing Then
                If (clickedLabel.Foreground.Equals(Color.FromRgb(0, 0, 0))) Then
                    Return
                End If
                If (firstClicked Is Nothing) Then
                    firstClicked = clickedLabel
                    firstClicked.Foreground = Br
                    Return
                End If
                secondClicked = clickedLabel
                secondClicked.Foreground = Br
                CheckForWinner()
                If (firstClicked.Content = secondClicked.Content) Then
                    firstClicked = Nothing
                    secondClicked = Nothing
                    Return
                End If
     
    
                myControl.Timer1.Start()
            End If
        End Sub
    
        Public Sub Timer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs)
            myControl.Timer1.Stop()
            firstClicked.Foreground = firstClicked.Background
            secondClicked.Foreground = secondClicked.Background
            firstClicked = Nothing
            secondClicked = Nothing
        End Sub
    End Class
    


  8. Class MainWindowクラスのコード解説
    (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クラスのコード
    Public Class UserControl1
        Public UC As MainWindow
        Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick
            UC.Timer_Tick(sender, e)
        End Sub
    End Class
    


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


    感想:
    (1)レイアウトはGrid機能を使用するとやりやすいです。
    (2)UserControl1クラスにタイマーを設定すると、Timer1_Tickは自動的にUserControl1クラスに設定されます。このためどうしてもUserControl1クラスからMainWindowクラスを呼びだす必要が生じました。
    (3)こんなとき、Meが重要な役割を果たします。






33章:チュートリアル32:WPFクラスを使用するに行く。

トップページに戻る。