如何为简单游戏创建棋盘,看起来像国际象棋,但用户可以动态更改列数和行数?在单元格中,我可以插入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;
答案 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>
课程 - 显然,您需要在Piece
和INotifyPropertyChanged
属性上实施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}}。
修改强>
我很久以前就写过这个答案了,这有问题。
使用应用于网格生成的项容器的样式分配ListBox
和ContentPresenter
属性是正确的。确定项容器是Grid.Row
并为该类型创建默认样式不是。 (在这种情况下它会可靠地工作,但是有很多情况下它不会。)
您仍然应该创建一个样式,但应该将其分配给Grid.Column
的{{1}}。此样式会自动应用于控件为其项目生成的任何容器元素 - 因此,如果您使用的ContentPresenter
为ItemsControl
,则会将其应用于ItemContainerStyle
,如果是一个ItemsControl
,它将应用于ListBox
,依此类推。