我无法使用 INotifyPropertyChanged 更新我的值
I can't get my value to update using INotifyPropertyChanged
所以我正在通过制作 yatzee 游戏来学习 WPF,并且我正在取得进展。但是现在我不明白为什么我的 "current roll" 计数器不会在视图中更新。我让骰子工作,掷骰子按钮为我的骰子提供了新值——这在视图中更新了。但是我的 "Current roll" 变量不会。这是我到目前为止所做的。
// CurrentRoll.cs
public class CurrentRoll : INotifyPropertyChanged
{
public int _roll;
public int Roll
{
get { return _roll; }
set
{
if (value != _roll)
{
_roll = value;
OnPropertyChanged("Roll");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
那么这是我的 DiceModelView。当我点击 "Roll Dices" 按钮时,只要未选中,我的所有骰子都会得到新值。我还增加了 _currentRoll 变量,并且只允许新的滚动,只要 _currentRoll 仍然小于 3。这个逻辑有效,变量有效,但它在视图中的表示没有。我还将其初始值更改为其他值,只是为了查看我的绑定是否有效,而且确实有效。
public class DiceModelView : INotifyPropertyChanged
{
Die _die;
public CurrentRoll _currentRoll;
public event PropertyChangedEventHandler PropertyChanged;
public ObservableCollection<Die> myDices { get; set; }
public ICommand RollCommand { get; set; }
public DiceModelView()
{
myDices = new ObservableCollection<Die>()
{
new Die { Id = 0, Roll = 0, Checked = false },
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 }
};
_currentRoll = new CurrentRoll();
_currentRoll._roll = 0;
RollCommand = new Command (executeMethod, canexecuteMethod);
}
public bool canexecuteMethod(object parameter)
{
return true;
}
private void executeMethod(object parameter)
{
var r = new Random();
if (_currentRoll._roll < 3)
{
foreach (Die d in myDices)
{
if (d.Checked == false)
{
d.Roll = r.Next(1, 7);
}
}
}
_currentRoll._roll++;
}
private void NotifyPropertyChanged(String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public Die die
{
get { return _die; }
set { _die = value; }
}
public CurrentRoll currentRoll
{
get { return _currentRoll; }
set { _currentRoll = value;
NotifyPropertyChanged("currentRoll");
}
}
最后,这是我使用的 XAML 代码:
<Window.DataContext>
<local:DiceModelView/>
</Window.DataContext>
<StackPanel>
<TextBlock Text="{Binding currentRoll.Roll, UpdateSourceTrigger=PropertyChanged}"/>
<ListView x:Name="DiceView" ItemsSource="{Binding myDices}" Width="500" HorizontalContentAlignment="Center" >
<ListView.ItemTemplate>
<DataTemplate >
<CheckBox Content="{Binding Roll}" IsChecked="{Binding Checked}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button Content="Roll the dices!" Command="{Binding RollCommand}"/>
</StackPanel>
</Window>
您需要更新 Roll
属性,而不是 _role
字段。
_roll
无论如何都应该是私有的。
想一想:您在 属性 setter 中引发了 属性 changed 事件,因此只有当您设置 [=20= 的值时才会执行此事件].
所以我正在通过制作 yatzee 游戏来学习 WPF,并且我正在取得进展。但是现在我不明白为什么我的 "current roll" 计数器不会在视图中更新。我让骰子工作,掷骰子按钮为我的骰子提供了新值——这在视图中更新了。但是我的 "Current roll" 变量不会。这是我到目前为止所做的。
// CurrentRoll.cs
public class CurrentRoll : INotifyPropertyChanged
{
public int _roll;
public int Roll
{
get { return _roll; }
set
{
if (value != _roll)
{
_roll = value;
OnPropertyChanged("Roll");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
那么这是我的 DiceModelView。当我点击 "Roll Dices" 按钮时,只要未选中,我的所有骰子都会得到新值。我还增加了 _currentRoll 变量,并且只允许新的滚动,只要 _currentRoll 仍然小于 3。这个逻辑有效,变量有效,但它在视图中的表示没有。我还将其初始值更改为其他值,只是为了查看我的绑定是否有效,而且确实有效。
public class DiceModelView : INotifyPropertyChanged
{
Die _die;
public CurrentRoll _currentRoll;
public event PropertyChangedEventHandler PropertyChanged;
public ObservableCollection<Die> myDices { get; set; }
public ICommand RollCommand { get; set; }
public DiceModelView()
{
myDices = new ObservableCollection<Die>()
{
new Die { Id = 0, Roll = 0, Checked = false },
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 }
};
_currentRoll = new CurrentRoll();
_currentRoll._roll = 0;
RollCommand = new Command (executeMethod, canexecuteMethod);
}
public bool canexecuteMethod(object parameter)
{
return true;
}
private void executeMethod(object parameter)
{
var r = new Random();
if (_currentRoll._roll < 3)
{
foreach (Die d in myDices)
{
if (d.Checked == false)
{
d.Roll = r.Next(1, 7);
}
}
}
_currentRoll._roll++;
}
private void NotifyPropertyChanged(String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public Die die
{
get { return _die; }
set { _die = value; }
}
public CurrentRoll currentRoll
{
get { return _currentRoll; }
set { _currentRoll = value;
NotifyPropertyChanged("currentRoll");
}
}
最后,这是我使用的 XAML 代码:
<Window.DataContext>
<local:DiceModelView/>
</Window.DataContext>
<StackPanel>
<TextBlock Text="{Binding currentRoll.Roll, UpdateSourceTrigger=PropertyChanged}"/>
<ListView x:Name="DiceView" ItemsSource="{Binding myDices}" Width="500" HorizontalContentAlignment="Center" >
<ListView.ItemTemplate>
<DataTemplate >
<CheckBox Content="{Binding Roll}" IsChecked="{Binding Checked}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button Content="Roll the dices!" Command="{Binding RollCommand}"/>
</StackPanel>
</Window>
您需要更新 Roll
属性,而不是 _role
字段。
_roll
无论如何都应该是私有的。
想一想:您在 属性 setter 中引发了 属性 changed 事件,因此只有当您设置 [=20= 的值时才会执行此事件].