【问题标题】:I can't get my value to update using INotifyPropertyChanged我无法使用 INotifyPropertyChanged 更新我的值
【发布时间】:2018-02-26 18:29:44
【问题描述】:

所以我正在通过制作一个 yatzee 游戏来学习 WPF,并且我正在取得进展。但现在我不明白为什么我的“当前滚动”计数器不会在视图中更新。我使骰子工作,掷骰子按钮为我的骰子提供了新值 - 这在视图中更新。但我的“当前滚动”变量不会。这是我到目前为止所做的。

// 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。当我点击“掷骰子”按钮时,只要未选中它们,我就会在所有骰子上获得新值。我还增加了 _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>

【问题讨论】:

  • 不相关:您有一个 public 字段和一个由该字段支持的 public 属性。您可以通过属性直接访问该字段。这迟早会在你面前适得其反。
  • @Fildor:为什么“不相关”?这正是这里的问题:)
  • @DanielHilgarth 哦,没想到居然能彻底解决问题。
  • 不太清楚我最终是如何做到的,我在 Die 类中以正确的方式做到了。但是你们俩都很好:)

标签: c# .net wpf mvvm inotifypropertychanged


【解决方案1】:

您需要更新Roll 属性,而不是_role 字段。

_roll 无论如何都应该是私有的。

想一想:您在属性设置器中引发了属性更改事件,因此只有在您设置属性值时才会执行此操作。

【讨论】:

  • 成功了!谢谢! _roll 是公开的事实是根本原因,intellisens 一直告诉我选择 _currentRoll._roll 而不是 _currentRoll.Roll。
  • @Tom:你的评论对我来说毫无意义。 Roll_roll 在您的班级中都不是私有的,至少不是您提供给我们的代码。
  • 错字。我的意思是公开的,对不起。将其设为私有就可以了。
猜你喜欢
  • 2020-06-03
  • 1970-01-01
  • 1970-01-01
  • 2018-01-12
  • 1970-01-01
  • 2013-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多