C# 获取由ItemsControl填充的网格的行和列位置
我想用wpf做一个扫雷游戏。我使用以下代码将游戏板设计为按钮网格:C# 获取由ItemsControl填充的网格的行和列位置,c#,wpf,C#,Wpf,我想用wpf做一个扫雷游戏。我使用以下代码将游戏板设计为按钮网格: <Window.Resources> <DataTemplate x:Key="DataTemplateLevel2"> <Button Content="{Binding}" Height ="30" Width="40" Click ="Execute"/> </DataTemplate> <DataTemplate x:Key
<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 buttonGrid=newlist();
对于(int r=0;r
问题是,当我单击按钮时,我的事件处理程序需要知道按钮的行和列,但是Grid.GetRow
和Grid.GetColumn
始终返回0。我认为这是因为网格只包含一个ItemsControl。如何在仍然允许动态网格大小的情况下获得有意义的行和列值?您需要详细了解。你的猜测大错特错了。这些按钮没有Grid.Row
或Grid.Column
值,因为您没有明确给它们任何值。此外,如果您这样做,那将是浪费时间,因为它们不在网格中。它们位于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;
ItemsControl的子项不是网格的直接子项。您可以整天为它们提供Grid.Row和Grid.Column值,但这不会产生任何效果,因为它们不是定义了多个行和列的网格的子级。相反,它们是由ItemsPanelTemplate
创建的StackPanel的子级。没有网格。只有堆叠面板。你想在这里做什么?因为网格不提供索引,所以我想从ItemsControls获取索引。click事件处理程序知道按下了哪个按钮,我只是不知道如何向ItemsControl询问它的位置。
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}");
}