2017-03-29 7 views
1

私はWPF C#でNxN tic tac toeゲームを作っています。私は、行と列の数(NxN)を入力するユーザーを、私のコードは、列と行の数を生成します。私はそれを理解することはできません、どのように動的に行と列の数を生成します。私はXAMLコードを投稿しましたが、XAMLコードをループする方法はありますか? おかげNxN tic tac toe GUIを作成するwpf c#

<Grid x:Name="Container"> 
    <!-- First here i want to make N columns--> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="*"/> 
     <ColumnDefinition Width="*"/> 
     <ColumnDefinition Width="*"/> 
    </Grid.ColumnDefinitions> 

    <!-- Here i want to make N rows--> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="*"/> 
     <RowDefinition Height="*"/> 
     <RowDefinition Height="*"/> 
    </Grid.RowDefinitions> 

    <!-- Then here i want to add that number of buttons in N x N columns and rows --> 
    <Button x:Name="Button0_0" Grid.Row="0" Grid.Column="0" Click="Button_Click"/> 
    <Button x:Name="Button0_1" Grid.Row="0" Grid.Column="1" Click="Button_Click" /> 
    <Button x:Name="Button0_2" Grid.Row="0" Grid.Column="2" Click="Button_Click"/> 

    <Button x:Name="Button1_0" Grid.Row="1" Grid.Column="0" Click="Button_Click"/> 
    <Button x:Name="Button1_1" Grid.Row="1" Grid.Column="1" Click="Button_Click"/> 
    <Button x:Name="Button1_2" Grid.Row="1" Grid.Column="2" Click="Button_Click"/> 

    <Button x:Name="Button2_0" Grid.Row="2" Grid.Column="0" Click="Button_Click"/> 
    <Button x:Name="Button2_1" Grid.Row="2" Grid.Column="1" Click="Button_Click"/> 
    <Button x:Name="Button2_2" Grid.Row="2" Grid.Column="2" Click="Button_Click"/>             
</Grid> 
+0

xamlの代わりにコードでビジュアルコンポーネントをビルドすることはできますが、それが行きたい方向なのかどうかわかりません。 –

+0

c#code ok ok、C#でバックエンドを書くのに便利なリンクがありますか? – Moin5262

答えて

0

のItemsControl + UniformGridは、長方形のゲームボードを表示するには良い選択です。私はすでに同様のソリューション(How to create and use matrix of (color) boxes C# WPF)を投稿しましたが、行と列のバインディングがありません。ここでは、TicTacToeのより精巧な例を示します。

のは、ビューモデルクラスを作成してみましょう:

public class BoardCell : INotifyPropertyChanged 
{ 
    private string _sign; 
    private bool _canSelect = true; 

    public string Sign 
    { 
     get { return _sign; } 
     set 
     { 
      _sign = value; 
      if (value != null) 
       CanSelect = false; 
      OnPropertyChanged(); 
     } 
    } 

    public bool CanSelect 
    { 
     get { return _canSelect; } 
     set 
     { 
      _canSelect = value; 
      OnPropertyChanged(); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 
    { 
     PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 
public class Board 
{ 
    public int Rows { get; set; } 
    public int Columns { get; set; } 

    private ObservableCollection<BoardCell> _cells; 
    public ObservableCollection<BoardCell> Cells 
    { 
     get 
     { 
      if (_cells == null) 
       _cells = new ObservableCollection<BoardCell>(Enumerable.Range(0, Rows*Columns).Select(i => new BoardCell())); 
      return _cells; 
     } 
    } 
} 

をして、ビューを作成します。コードビハインドで

<Grid x:Name="Container"> 
    <Grid.DataContext> 
     <wpfDemos:Board Rows="8" Columns="8"/> 
    </Grid.DataContext> 
    <ItemsControl x:Name="Board" ItemsSource="{Binding Path=Cells}"> 
     <ItemsControl.ItemsPanel> 
      <ItemsPanelTemplate > 
       <UniformGrid Rows="{Binding Path=Rows}" Columns="{Binding Path=Columns}"/> 
      </ItemsPanelTemplate> 
     </ItemsControl.ItemsPanel> 

     <ItemsControl.ItemTemplate> 
      <DataTemplate> 
       <Button Content="{Binding Path=Sign}" 
         IsEnabled="{Binding Path=CanSelect}" 
         Click="CellClick"/> 
      </DataTemplate> 
     </ItemsControl.ItemTemplate> 
    </ItemsControl> 
</Grid> 

我々は2人の選手がthierを作ることを可能にする一つの方法を持っています順番に移動する:

MVVMパターンに従うには、このメソッドをコマンド(ICommand)にラップし、Boardクラスに移動し、Button.Commandバインド経由でビューに添付する必要があります。

board after some turns

概要:別のロジックとプレゼンテーション。データを扱うコントロールがバインディングと提供されたテンプレートに基づいてコンテンツを生成できるようにします。

+0

ありがとうございました! – Moin5262

0

私は正確にこれを行うcode for some AttachedProperties on my blogを持っています。

XAMLコードはこのように見える終わる:

<Grid local:GridHelpers.RowCount="{Binding RowCount}" 
     local:GridHelpers.ColumnCount="{Binding ColumnCount}" /> 

ブログ記事のリンクが今までダウンした場合にはここで、添付プロパティのコードです。スターの行/列を指定するプロパティもあります。ゾハルはあなたがGrid.ColumnDefinitionsに子GridColumn年代を追加するための背後にあるコードを使用して、コンテナグリッドにボタンのを追加することができます言及したように

public class GridHelpers 
{ 
    #region RowCount Property 

    /// <summary> 
    /// Adds the specified number of Rows to RowDefinitions. 
    /// Default Height is Auto 
    /// </summary> 
    public static readonly DependencyProperty RowCountProperty = 
     DependencyProperty.RegisterAttached(
      "RowCount", typeof(int), typeof(GridHelpers), 
      new PropertyMetadata(-1, RowCountChanged)); 

    // Get 
    public static int GetRowCount(DependencyObject obj) 
    { 
     return (int)obj.GetValue(RowCountProperty); 
    } 

    // Set 
    public static void SetRowCount(DependencyObject obj, int value) 
    { 
     obj.SetValue(RowCountProperty, value); 
    } 

    // Change Event - Adds the Rows 
    public static void RowCountChanged(
     DependencyObject obj, DependencyPropertyChangedEventArgs e) 
    { 
     if (!(obj is Grid) || (int)e.NewValue < 0) 
      return; 

     Grid grid = (Grid)obj; 
     grid.RowDefinitions.Clear(); 

     for (int i = 0; i < (int)e.NewValue; i++) 
      grid.RowDefinitions.Add(
       new RowDefinition() { Height = GridLength.Auto }); 

     SetStarRows(grid); 
    } 

    #endregion 

    #region ColumnCount Property 

    /// <summary> 
    /// Adds the specified number of Columns to ColumnDefinitions. 
    /// Default Width is Auto 
    /// </summary> 
    public static readonly DependencyProperty ColumnCountProperty = 
     DependencyProperty.RegisterAttached(
      "ColumnCount", typeof(int), typeof(GridHelpers), 
      new PropertyMetadata(-1, ColumnCountChanged)); 

    // Get 
    public static int GetColumnCount(DependencyObject obj) 
    { 
     return (int)obj.GetValue(ColumnCountProperty); 
    } 

    // Set 
    public static void SetColumnCount(DependencyObject obj, int value) 
    { 
     obj.SetValue(ColumnCountProperty, value); 
    } 

    // Change Event - Add the Columns 
    public static void ColumnCountChanged(
     DependencyObject obj, DependencyPropertyChangedEventArgs e) 
    { 
     if (!(obj is Grid) || (int)e.NewValue < 0) 
      return; 

     Grid grid = (Grid)obj; 
     grid.ColumnDefinitions.Clear(); 

     for (int i = 0; i < (int)e.NewValue; i++) 
      grid.ColumnDefinitions.Add(
       new ColumnDefinition() { Width = GridLength.Auto }); 

     SetStarColumns(grid); 
    } 

    #endregion 

    #region StarRows Property 

    /// <summary> 
    /// Makes the specified Row's Height equal to Star. 
    /// Can set on multiple Rows 
    /// </summary> 
    public static readonly DependencyProperty StarRowsProperty = 
     DependencyProperty.RegisterAttached(
      "StarRows", typeof(string), typeof(GridHelpers), 
      new PropertyMetadata(string.Empty, StarRowsChanged)); 

    // Get 
    public static string GetStarRows(DependencyObject obj) 
    { 
     return (string)obj.GetValue(StarRowsProperty); 
    } 

    // Set 
    public static void SetStarRows(DependencyObject obj, string value) 
    { 
     obj.SetValue(StarRowsProperty, value); 
    } 

    // Change Event - Makes specified Row's Height equal to Star 
    public static void StarRowsChanged(
     DependencyObject obj, DependencyPropertyChangedEventArgs e) 
    { 
     if (!(obj is Grid) || string.IsNullOrEmpty(e.NewValue.ToString())) 
      return; 

     SetStarRows((Grid)obj); 
    } 

    #endregion 

    #region StarColumns Property 

    /// <summary> 
    /// Makes the specified Column's Width equal to Star. 
    /// Can set on multiple Columns 
    /// </summary> 
    public static readonly DependencyProperty StarColumnsProperty = 
     DependencyProperty.RegisterAttached(
      "StarColumns", typeof(string), typeof(GridHelpers), 
      new PropertyMetadata(string.Empty, StarColumnsChanged)); 

    // Get 
    public static string GetStarColumns(DependencyObject obj) 
    { 
     return (string)obj.GetValue(StarColumnsProperty); 
    } 

    // Set 
    public static void SetStarColumns(DependencyObject obj, string value) 
    { 
     obj.SetValue(StarColumnsProperty, value); 
    } 

    // Change Event - Makes specified Column's Width equal to Star 
    public static void StarColumnsChanged(
     DependencyObject obj, DependencyPropertyChangedEventArgs e) 
    { 
     if (!(obj is Grid) || string.IsNullOrEmpty(e.NewValue.ToString())) 
      return; 

     SetStarColumns((Grid)obj); 
    } 

    #endregion 

    private static void SetStarColumns(Grid grid) 
    { 
     string[] starColumns = 
      GetStarColumns(grid).Split(','); 

     for (int i = 0; i < grid.ColumnDefinitions.Count; i++) 
     { 
      if (starColumns.Contains(i.ToString())) 
       grid.ColumnDefinitions[i].Width = 
        new GridLength(1, GridUnitType.Star); 
     } 
    } 

    private static void SetStarRows(Grid grid) 
    { 
     string[] starRows = 
      GetStarRows(grid).Split(','); 

     for (int i = 0; i < grid.RowDefinitions.Count; i++) 
     { 
      if (starRows.Contains(i.ToString())) 
       grid.RowDefinitions[i].Height = 
        new GridLength(1, GridUnitType.Star); 
     } 
    } 
} 
0

。その簡単なアプローチですが、多くの悩みの原因となるコードの背後にあることを意味します。

個人的に私はむしろ行動を作成し、それをグリッドに添付したいと思います。あなたの振る舞いをviewmodelの列と列の整数にバインドし、ColumnDefinitionsとRowDefinitionsをAssociatedObjectに追加します。ビヘイビアは、再利用可能な機能をカプセル化する優れた方法であり、コードを記述する必要はありません。

この章では、モデルにバインドするビヘイビアを作成する方法と、ビヘイビアをビュー内の要素にアタッチする方法について説明します。パネルとして

http://julmar.com/blog/programming/playing-with-wpf-behaviors-a-watermarktext-behavior/