2017-09-11 4 views
0

私はWPF/MVVMを学ぶためにYahtzeeゲームを作っています。私はいくつかの進歩を遂げましたが、私はICommandを使って私のダイスにランダムなint値(ローリング)を与える方法を苦労しています。だから私はこのようにダイスクラスを持っている:ICommandを使用してモデルのプロパティを変更するにはどうすればよいですか?

public class Die : INotifyPropertyChanged 
    { 
     int _id; 
     int _roll; 
     bool _checked; 
    } 

これらのプロパティは、すべてこのようなコンストラクタを持っている:

public bool Checked 
    { 
     get { return _checked; } 
     set { _checked = value; 
      OnPropertyChanged("Checked"); } 
    } 

「_id」はサイコロを追跡するだけの方法で、さえわからないことです必要です。 "_roll"はランダムな値で、手元の質問です。 "_checked"は、次の投げにこの値を保持したい場合、プレイヤーがチェックを入れることができるチェックボックスです。

私のViewModelには、次のようになります。

public class DiceViewModel : INotifyPropertyChanged 
{ 
    Die _die; 

    public DiceViewModel() 
    { 
     myDices = new ObservableCollection<Die>() 
     { 
      new Die { Id = 1, Roll = 0, Checked = false }, 
      new Die { Id = 2, Roll = 0, Checked = false }, 
      new Die { Id = 3, Roll = 0, Checked = false }, 
      new Die { Id = 4, Roll = 0, Checked = false }, 
      new Die { Id = 5, Roll = 0, Checked = false }, 
     }; 
    } 
} 

コマンドを作成での私の最高の試みは、このようなものです:

public class RollDiceCommand : ICommand 
{ 
    private Action<object> _method; 
    public event EventHandler CanExecuteChanged; 

    public RollDiceCommand(Action<object> method) 
    { 
     _method = method; 
    } 

    public bool CanExecute (object parameter) 
    { 
     if ((bool)parameter == true) 
     { 
      return true; 
     } 
     else 
      return false; 
    } 

    public void Execute(object parameter) 
    { 

    } 
} 

だから私は作成する方法を理解できない二つのものがどのようにあります各ダイスの_checkedプロパティがfalseかどうかを確認し、falseの場合は現在のDieに新しい番号を与えます。私はまた、 "ロールダイス"ボタンを押した後、5つのダイスすべてをループする必要があります。

  1. RollDiceCommandを独自のファイルにする必要がありますか、それともVM/Mに入れる必要がありますか?
  2. CanExecuteパラメータとして_checkedプロパティを取得する方法
  3. 1つのダイスの_roll値をランダム化する方法は、2の質問もこの問題を解決すると思います。
+0

私はあなたに何を伝えるべきかわかりません、ここでうまくいきます。少なくとも、コンパイルしてクラッシュすることなく実行できます。 編集:私はあなたが今何を意味するかを見て、それを編集するつもりです。 – Tom

+0

今日私は眠くて、私はなぜそこに置くのか分かりません。 – Tom

答えて

0

私は私はそれを行う方法の方法であなたを助けるためにしようとするでしょう:

1)のObservableCollectionは正しい選択ですが、そのコレクションからに関する情報が必要な場合は、なぜプロパティを作成していません?そして、あなたは民間の書き込みに/リストを作成することができ、外部にそれはあなたのコマンドは、接続されているGUIである場合にのみ読める

public class DiceViewModel : INotifyPropertyChanged 
    { 
     Die _die; 

     public DiceViewModel() 
     { 
      mMyDices= new ObservableCollection<Die>() 
      { 
       new Die { _id = 1, _roll = 0, _checked = false }, 
       new Die { _id = 2, _roll = 0, _checked = false }, 
       new Die { _id = 3, _roll = 0, _checked = false }, 
       new Die { _id = 4, _roll = 0, _checked = false }, 
       new Die { _id = 5, _roll = 0, _checked = false }, 
      }; 
     } 
    private ObservableCollection<Die> mMyDices; 
    public ObservableCollection<Die> MyDices 
    { 
    public get {retrun mMyDices; } 
    private set { SetProperty (mMyDices, value);  } 
    //This is part from interface IProperty changed 
    } 
} 

2)は、[はいVM 3)あなたがCanExecuteメソッドを実装するクラスにそれを置くだろう、 MyDicesリストにアクセスする必要があります。プロパティを取得するには、プロパティを作成する必要があります。

あなたのダイスクラスには3つのプライベート変数があります。これはちょうど1のように、目に見える内部でのみです)、彼らに財産を作るために:

//to outside read-only, but only in Dice class is writable 
public Checked {get; private set;} 

//to outside writable, readable 
public Checked {get; set;} 

UPDATE:

public abstract class BaseViewModel: INotifyPropertyChanged 
    { 
     /// <summary> 
     ///  Multicast event for property change notifications. 
     /// </summary> 
     public event PropertyChangedEventHandler PropertyChanged; 

     /// <summary> 
     ///  Checks if a property already matches a desired value. Sets the property and 
     ///  notifies listeners only when necessary. 
     /// </summary> 
     /// <typeparam name="T">Type of the property.</typeparam> 
     /// <param name="storage">Reference to a property with both getter and setter.</param> 
     /// <param name="value">Desired value for the property.</param> 
     /// <param name="propertyName"> 
     ///  Name of the property used to notify listeners. This 
     ///  value is optional and can be provided automatically when invoked from compilers that 
     ///  support CallerMemberName. 
     /// </param> 
     /// <returns> 
     ///  True if the value was changed, false if the existing value matched the 
     ///  desired value. 
     /// </returns> 
     protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] String propertyName = null) { 
      if (Equals(storage, value)) { 
       return false; 
      } 

      storage = value; 
      this.OnPropertyChanged(propertyName); 
      return true; 
     } 

     /// <summary> 
     ///  Notifies listeners that a property value has changed. 
     /// </summary> 
     /// <param name="propertyName"> 
     ///  Name of the property used to notify listeners. This 
     ///  value is optional and can be provided automatically when invoked from compilers 
     ///  that support <see cref="CallerMemberNameAttribute" />. 
     /// </param> 
     protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { 
      PropertyChangedEventHandler eventHandler = this.PropertyChanged; 
      if (eventHandler != null) { 
       eventHandler(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 
} 

私が作成したVMの基本クラスを持っています。

+0

"SetProperty"を動作させるように見えません。 "私のエラーメッセージは"名前 'SetProperty'は存在しません現在のコンテキスト – Tom

+0

こんにちはTom、申し訳ありませんが、私のBaseクラスからコードを更新するのを忘れました。 –

関連する問題