2017-05-03 73 views
0

我正在尝试使用wpf来制作扫雷游戏。我设计的游戏板为用下面的代码按钮的网格:获取由一个ItemsControl填充的Grid和Colum位置

<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.GetRowGrid.GetColumn总是返回0.我认为这是因为网格只包含一个ItemsControl。如何获得有意义的行和列值,同时仍然允许动态网格大小?

+1

ItemsControl的子项不是网格的直接子元素。您可以整天给它们使用Grid.Row和Grid.Column值,并且它不会起作用,因为它们不是定义了多行和多列的Grid的子项。相反,它们是由'ItemsPanelTemplate'创建的StackPanel的子项。没有网格。只有StackPanel。你想在这里做什么? –

+0

由于网格不会提供索引,我想从ItemsControls获取索引。点击事件处理程序知道哪个按钮被按下,我只是不知道如何询问ItemsControl的位置。 – Kevlarz

回答

0

您需要阅读约what a Grid does in WPF。你的猜测是疯狂的基础。这些按钮没有Grid.RowGrid.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}"); 
}