简体   繁体   中英

I can't get my value to update using INotifyPropertyChanged

So I am learning WPF by making a yatzee game, and I'm getting somewhere. But now I can not understand why I my "current roll" counter won't update in the View. I made the Dices work, and the roll dices button gives my dices new values - and this is updated in the view. But my "Current roll" variable will not. This is what I've done so far.

// 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));
        }
    }
}

Then this is my DiceModelView. When I hit my "Roll Dices" button I get new values on all my dices as long as they are left unchecked. I also increment the _currentRoll variable, and only allow new rolls as long as _currentRoll still is less than 3. This logic works, the variable works, but it's representation in the View does not. I've also changed its initial value to other values just to see that my binding works, and it does.

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");
        }
    }

现在,我的应用程序如何运行,在此示例中,我将_currentRoll._roll设置为111只是为了确保它能正常工作。我没有掷骰子,因为上述值大于3。

Finally, this is the XAML code I use:

<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>

You need to update the Roll property, not the _role field.

_roll should be private anyway.

Just think about it: You are raising the property changed event in the property setter, so this only get's executed when you set the value of the property.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM