1

現在、WPF と XAML を学ぶために connect-4 ゲームを作成しています。UI を作成しましたが、問題が発生しています。

以下に、ゲームのボードに関する XAML コードの抜粋を示します。

<Grid DockPanel.Dock="Bottom" Background="#FF1506A4" MouseLeftButtonUp="Grid_MouseLeftButtonUp_1">
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            ... 5 more rows
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            ... 6 more columns
        </Grid.ColumnDefinitions>
        <Ellipse Grid.Row="0" Grid.Column="0" Fill="White" Margin="8"/>
        ... 41 more ellipses
</Grid>

ボードは、GameState クラスの Token (Empty、Red、Yellow の列挙) の配列に格納されます。

楕円の色は、SolidBrushColor クラスを使用して提供されます。

私の問題は、ゲーム モデルに応じて楕円の色を変更する方法がわからないことです。

データ バインディングを使用する必要があると思いますが、データをバインドする前に、色を Token 型から SolidBrushColor 型に変換する必要があります。いくつかの DataObjectProvider オブジェクトを使用して実現できると思いますが、このような単純なタスクのために 42 個の DataObjectProvider オブジェクトを作成するのは複雑すぎるようです...

それでは、最善の方法によると、正しい解決策は何でしょうか?

4

3 に答える 3

3

バックエンドである種の ViewModel を使用してから、DataBinding を活用します。

Connect Four ボードを表す次の (考案された) ViewModel 構造を想定しています。

BoardViewModel.cs

public class BoardViewModel
{
    public BoardViewModel()
    {
        var rand = new Random();
        Squares = Enumerable
            .Range(1, 42)
            .Select(a => new SquareViewModel() { Token = rand.Next(-1, 2) })
            .ToList();
    }

    public List<SquareViewModel> Squares { get; set; }
}

SquareViewModel.cs

public class SquareViewModel : INotifyPropertyChanged
{
    private int _Token;
    public int Token
    {
        get
        {
            return _Token;
        }
        set
        {
            if (_Token.Equals(value)) return;

            _Token = value;
            RaisePropertyChanged("Token");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void RaisePropertyChanged(string property)
    {
        var handlers = PropertyChanged;
        if (handlers != null)
        {
            var args = new PropertyChangedEventArgs(property);
            handlers(this, args);
        }
    }
}

次に、次の XAML を使用してボードを表すことができます。

MainWindow.xaml

<Window 
    x:Class="ConnectFour.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    mc:Ignorable="d" 
    xmlns:ConnectFour="clr-namespace:ConnectFour"
    Title="MainWindow" Height="350" Width="525"
    d:DataContext="{d:DesignInstance Type={x:Type ConnectFour:BoardViewModel}, IsDesignTimeCreatable=True}">
    <ItemsControl
        ItemsSource="{Binding Squares}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Ellipse
                    Stroke="Magenta">
                    <Ellipse.Style>
                        <Style TargetType="Ellipse">
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding Token}" Value="0">
                                    <Setter Property="Fill" Value="Black" />
                                </DataTrigger>
                                <DataTrigger Binding="{Binding Token}" Value="1">
                                    <Setter Property="Fill" Value="Red" />
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </Ellipse.Style>
                </Ellipse>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <UniformGrid IsItemsHost="True" Columns="6" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>
</Window>

注意すべき重要事項は次のとおりです。

  • Square の Token プロパティの値に基づいて楕円の色を設定する DataTriggers。
  • バックアップする UniformGrid を使用した ItemsPanel の使用。
  • SquareViewModel に INotifyPropertyChanged を実装して、トークンの値が変更されたときにビューがそれを表すようにします。
  • d:DataContext 属性の使用。これは、フォームの設計時の DataContext を BoardViewModel のインスタンスに設定します (それ自体をランダムなトークンに初期化します)。

実行時に、ボード ビューの DataContext を BoardViewModel (または ViewModel が呼び出されたもの) の実際のインスタンスに設定する必要がありますが、トークンの色を変更する方法の基本的な考え方は存在します。

于 2014-01-08T03:11:21.653 に答える