2017-05-03 42 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}"); 
}