2017-05-03 10 views
0

wpfを使用して地雷探偵ゲームを作成しようとしています。グリッドの行と列の位置をItemsControlによって設定します。

<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を返します。これは、グリッドに1つのItemsControlしか含まれていないためです。ダイナミックグリッドサイズを許可しながら、有意な行と列の値を取得するにはどうすればよいですか?

+1

グリッドの子は、直接ItemsControlの子ではありません。それらにGrid.RowとGrid.Columnの値を一日中与えることができ、複数の行と列が定義されているグリッドの子ではないため、何の効果もありません。代わりに、あなたの 'ItemsPanelTemplate'によって作成されたStackPanelの子です。グリッドはありません。 StackPanelのみ。ここで何をしようとしていますか? –

+0

グリッドはインデックスを提供しないので、ItemsControlsからインデックスを取得したいと考えています。クリックイベントハンドラは、どのボタンが押されたかを知っていますが、ItemsControlにその位置を問い合わせる方法はわかりません。 – Kevlarz

答えて

0

what a Grid does in WPFを読んでください。あなたの推測は根元から大きく外れています。これらのボタンには、明示的に指定していないので、Grid.RowまたはGrid.Columnという値はありません。さらに、Gridに入っていないので、あなたがした場合は時間の無駄でしょう。彼らはあなたのItemsPanelTemplateによって作成されたStackPanelの中にあるContentPresenterにいる(ベッカはそれを見ていない!)。

とにかくこれを行う必要はありません。ここであなたができることがあります。

まず、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}"); 
} 
関連する問題