2 votes

création d'un plateau de jeu avec prise en charge des événements dans WPF

Comment puis-je créer un plateau pour un jeu simple, ressemblant aux échecs, mais l'utilisateur peut changer dynamiquement le nombre de colonnes et de lignes ? Dans les cellules, je pourrais insérer le symbole du pion, comme une petite image ou simplement une ellipse ou un rectangle avec remplissage. Ce plateau devrait permettre d'ajouter et de retirer des pions des cellules et de les déplacer d'une cellule à l'autre.

Ma première idée était la grille. Je l'ai fait dans le code derrière, mais il est difficile d'implémenter des événements ou tout dans le runtime créer le conseil :/

        int size = 12;
        Grid board = new Grid();
        board.ShowGridLines = true;
        for (int i = 0; i < size;i++ )
        {
            board.ColumnDefinitions.Add(new ColumnDefinition());
            board.RowDefinitions.Add(new RowDefinition());
        }

        //komputer
        Rectangle ai = new  Rectangle();
        ai.Height = 20;
        ai.Width = 20;
        ai.AllowDrop = true;
        ai.Fill = Brushes.Orange;
        Grid.SetRow(ai, 0);
        Grid.SetColumn(ai,0);
        //czowiek
        Rectangle hum = new Rectangle();
        hum.Height = 20;
        hum.Width = 20;
        hum.AllowDrop = true;
        hum.Fill = Brushes.Green;
        Grid.SetRow(hum,size);
        Grid.SetColumn(hum,size);
        board.Children.Add(ai);
        board.Children.Add(hum);
        this.Content = board;
  • Y a-t-il un moyen de faire ce changement dynamique de colonne et de ligne dans le XAML ?
  • La meilleure façon d'implémenter ce tableau est de créer et d'implémenter des événements pour déplacer un pion d'une cellule à une autre ?

2voto

Robert Rossney Points 43767

Vous devrez toujours utiliser le code-behind pour modifier l'adresse de l'utilisateur. RowDefinitions y ColumnDefinitions les propriétés de la Grid dans cet exemple, puisqu'il ne s'agit pas de propriétés de dépendance. Mais tout le reste de la logique peut être géré dans la classe du modèle de vue.

Le XAML :

<Window x:Class="GameBoard.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:GameBoard="clr-namespace:GameBoard"
        Title="Window1"
        SizeToContent="WidthAndHeight">
    <Grid Margin="50">
        <Grid.Resources>

            <!-- This template presents the Piece object.  Note that you can't set
                 the Grid.Row and Grid.Column properties on this Rectangle - well,
                 you *can*, but the Grid won't see them.  See the Style below.  -->
            <DataTemplate DataType="{x:Type GameBoard:Piece}">
                <Rectangle Fill="{Binding Fill}"
                           Width="50"
                           Height="50" />
            </DataTemplate>

            <!-- When the ItemsControl creates its items, it wraps each item in a
                 ContentPresenter.  You have to set Grid.Row and Grid.Column
                 on this ContentPresenter in order for the Grid to see them. -->
            <Style TargetType="{x:Type ContentPresenter}">
                <Setter Property="Grid.Row"
                        Value="{Binding Row}" />
                <Setter Property="Grid.Column"
                        Value="{Binding Column}" />
            </Style>

        </Grid.Resources>
        <Border BorderBrush="Black"
                BorderThickness="1">
            <ItemsControl x:Name="Board"
                          ItemsSource="{Binding}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="50" />
                                <RowDefinition Height="50" />
                                <RowDefinition Height="50" />
                                <RowDefinition Height="50" />
                                <RowDefinition Height="50" />
                                <RowDefinition Height="50" />
                                <RowDefinition Height="50" />
                                <RowDefinition Height="50" />
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="50" />
                                <ColumnDefinition Width="50" />
                                <ColumnDefinition Width="50" />
                                <ColumnDefinition Width="50" />
                                <ColumnDefinition Width="50" />
                                <ColumnDefinition Width="50" />
                                <ColumnDefinition Width="50" />
                                <ColumnDefinition Width="50" />
                            </Grid.ColumnDefinitions>
                        </Grid>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>
        </Border>
    </Grid>
</Window>

En Piece Vous devrez évidemment implémenter la classe INotifyPropertyChanged sur le Row y Column des propriétés pour gérer le déplacement des pièces.

public class Piece
{
    public int Column { get; set; }
    public Brush Fill { get; set; }
    public int Row { get; set; }
}

Remplir le tableau :

    public Window1()
    {
        InitializeComponent();

        ObservableCollection<Piece> pieces = new ObservableCollection<Piece>();
        pieces.Add(
            new Piece {Row = 0, Column = 0, Fill = new SolidColorBrush(Colors.BlanchedAlmond)});
        pieces.Add(
            new Piece {Row = 7, Column = 7, Fill = new SolidColorBrush(Colors.RosyBrown)});
        pieces.Add(
            new Piece { Row = 3, Column = 4, Fill = new SolidColorBrush(Colors.BlueViolet) });
        pieces.Add(
            new Piece { Row = 5, Column = 4, Fill = new SolidColorBrush(Colors.Orange) });

        Board.DataContext = pieces;
    }

J'ai utilisé un ItemsControl pour contenir les pièces dans cet exemple. Vous pourriez utiliser un ListBox à la place - c'est plutôt bien parce que cela vous permet de sélectionner les articles gratuitement. Notez que si vous faites cela, vous devrez modifier le champ Style 's TargetType a ListBoxItem puisque c'est ce que le ListBox enveloppe ses éléments d'éléments dans au lieu de ContentPresenter .

Edit :

J'ai écrit cette réponse il y a un certain temps, et il y a un problème.

Attribution de la Grid.Row y Grid.Column en utilisant un style appliqué au conteneur de l'élément généré par la grille est correcte. Le fait que le conteneur de l'élément soit un ContentPresenter et la création d'un style par défaut pour ce type ne l'est pas. (Cela fonctionnera de manière fiable dans ce cas, mais il y a beaucoup de cas où cela ne fonctionnera pas).

Vous devez quand même créer un style, mais il doit être attribué à l'élément ItemsControl 's ItemContainerStyle . Ce style est automatiquement appliqué à tout élément de conteneur que le contrôle génère pour ses éléments - ainsi, si l'élément ItemsControl que vous utilisez est un ListBox il l'appliquera à l ListBoxItem et si c'est un TabControl il sera appliqué à la TabItem et ainsi de suite.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X