在WPF中创建具有事件支持的游戏板

时间:2010-04-02 19:08:22

标签: c# wpf xaml

如何为简单游戏创建棋盘,看起来像国际象棋,但用户可以动态更改列数和行数?在单元格中,我可以插入pawn的符号,如小图像或只是椭圆或带填充的矩形。该板应该有可能添加和删除单元格中的pawn并将pown从一个单元格移动到另一个单元格。

我的第一个想法是Grid。我在后面的代码中执行它,但是在运行时创建板上实现事件或所有内容是有害的:/

        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);
        //człowiek
        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;
  • 这是一种在XAML中动态col和行更改的方法吗?
  • 这是一个更好的方法来实现该板创建和实现从一个单元格移动到另一个单元格的事件?

1 个答案:

答案 0 :(得分:2)

在此示例中,您仍然必须使用代码隐藏来更改RowDefinitions的{​​{1}}和ColumnDefinitions属性,因为它们不是依赖项属性。但是其余的逻辑都可以在视图模型类中处理。

XAML:

Grid

<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> 课程 - 显然,您需要在PieceINotifyPropertyChanged属性上实施Row来处理移动部分。

Column

填充董事会:

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

我已使用 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; } 来包含此示例中的各个部分。您可以使用ItemsControl代替 - 这样很好,因为它可以免费为您提供项目选择。请注意,如果您这样做,则必须将ListBox的{​​{1}}更改为Style,因为TargetType包含其项元素而非ListBoxItem 1}}。

修改

我很久以前就写过这个答案了,这有问题。

使用应用于网格生成的项容器的样式分配ListBoxContentPresenter属性是正确的。确定项容器是Grid.Row并为该类型创建默认样式不是。 (在这种情况下它会可靠地工作,但是有很多情况下它不会。)

您仍然应该创建一个样式,但应该将其分配给Grid.Column的{​​{1}}。此样式会自动应用于控件为其项目生成的任何容器元素 - 因此,如果您使用的ContentPresenterItemsControl,则会将其应用于ItemContainerStyle,如果是一个ItemsControl,它将应用于ListBox,依此类推。