2017-09-11 69 views
0

我正在制作一个Yahtzee游戏,试图学习WPF/MVVM。我已经取得了一些进展,但是我正在努力如何使用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”是一个复选框,玩家可以检查是否他想保留这个值用于下一次投掷。

我的视图模型是这样的:

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,则给当前的Die一个新的数字。点击我的“Roll Dice”按钮后,我还需要循环所有5个骰子。

  1. 我需要做RollDiceCommand到它自己的文件,或者把它与VM/M?
  2. 如何获取_checked属性作为CanExecute参数
  3. 如何随机化一个骰子的_roll值,我猜问题2也解决了这个问题。
+0

我不知道该告诉你什么,它在这里工作得很好。或者至少它编译和运行没有崩溃。 编辑:我明白你的意思,现在就编辑它。 – Tom

+0

我今天很困,我看到了,我不知道为什么我把“在那里。” – Tom

回答

0

我会尽力帮助你的方式,我如何做到这一点:

1)的ObservableCollection是正确的选择,但如果你从收集需要的相关信息,为什么不把财产???然后你就可以在私有写/创建列表和外面这将是唯一可读

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列表。要获得propertys,您需要创建它们。

你的骰子类有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)); 
      } 
     } 
} 

我已经创建了一个虚拟机的基类。

+0

我似乎无法得到“SetProperty”的工作,我的错误消息说“名称'SetProperty'不存在当前的情况。 – Tom

+0

嗨汤姆,对不起,我忘了更新我的基类的代码,这只会更新我的VM属性。 –