我正在尝试使用WPF制作扫雷游戏。我使用以下代码将游戏板设计为按钮网格:
<Window.Resources>
<DataTemplate x:Key="DataTemplateLevel2">
<Button Content="{Binding}" Height ="30" Width="40" Click ="Execute"/>
</DataTemplate>
<DataTemplate x:Key ="DataTemplateLevel1">
<ItemsControl ItemsSource ="{Binding}" ItemTemplate="{DynamicResource DataTemplateLevel2}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</DataTemplate>
</Window.Resources>
<Grid>
<ItemsControl x:Name ="Field" ItemTemplate="{DynamicResource DataTemplateLevel1}" />
</Grid>
和
List<List<int?>> buttonGrid = new List<List<int?>>();
for (int r = 0; r < Rows; r++)
{
buttonGrid.Add(new List<int?>());
for (int c = 0; c < Cols; c++)
{
buttonGrid[r].Add(null);
}
}
InitializeComponent();
Field.ItemsSource = buttonGrid;
。
问题是,当我单击一个按钮时,我的事件处理程序需要知道按钮的行和列,但是Grid.GetRow
和Grid.GetColumn
始终返回0。我认为这是因为网格仅包含一个ItemScontrol。我如何在仍允许动态网格尺寸的同时获得有意义的行和列值?
您需要阅读有关Grid
在WPF中所做的事情。您的猜测很疯狂。这些按钮没有Grid.Row
或Grid.Column
值,因为您没有明确给它们。此外,如果您不在Grid
中,那将是浪费时间。他们在ContentPresenter
中(Betcha没有看到即将到来!(,它是由您的ItemsPanelTemplate
创建的StackPanel
。
您不需要做任何事情。这是您可以做的。
首先,写一个简单的类以表示buttonGrid
中的网格单元。int?
无法保留您需要的所有信息。
public class GridCellItem
{
public GridCellItem()
{
}
public GridCellItem(int r, int c, int? v = null)
{
Row = r;
Col = c;
Value = v;
}
public int Row { get; set; }
public int Col { get; set; }
public int? Value { get; set; }
}
接下来,用与您所拥有的非常相似的代码填充网格:
List<List<GridCellItem>> buttonGrid = new List<List<GridCellItem>>();
for (int r = 0; r < Rows; r++)
{
buttonGrid.Add(new List<GridCellItem>());
for (int c = 0; c < Cols; c++)
{
buttonGrid[r].Add(new GridCellItem(r, c));
}
}
Field.ItemsSource = buttonGrid;
完成了所有这些,这是鼠标点击处理程序从单击的项目中获取行,列和价值信息的方式:
private void Execute(object sender, RoutedEventArgs e)
{
var cellItem = ((Button)sender).DataContext as GridCellItem;
// Replace this with code that does something useful, of course.
MessageBox.Show($"User clicked cell at row {cellItem.Row}, column {cellItem.Col}, with value {cellItem.Value}");
}