c# - WPF - 更改对象属性时通知 ViewModel

标签 c# wpf mvvm propertychanged

我是 WPF 和 MVVM 的新手(以及一般的编程),所以提前为 noobish 问题感到抱歉,但我真的很想在 MVVM 中完成这项工作

我有一个 ObservableCollection 类和我使用它的 ViewModel,现在我想在每次更改 UI 中的“角色”时计算 ViewModel 中的 OreMineTotal 和 OreTransportTotal(双向绑定(bind))。

这现在有效,但仅当我从 ObservableCollection 添加或删除项目时。

第一个问题
当我在 UI 中更改玩家角色时,为什么 ViewModel 中的玩家 ObservableCollection 的 setter 没有触发。

第二
如何在 MVVM 中解决这个问题,我想知道如何从 ViewModel 拦截/订阅 Player 类中的 RaisePropertyChanged("Role")

在winforms中我会在(鼠标点击或其他)事件中处理它,我改变玩家角色,但我想做MVVM风格

namespace MiningCalc.Model
{
public class Player : INotifyPropertyChanged
{

    public Player()
    {
        items = new ObservableCollection<MinedItems>();
    }
    private string name;
    private string mass;
    private int fc;
    private int boost;
    private int log;
    private int role;
    private ObservableCollection<MinedItems> items;

    public ObservableCollection<MinedItems> Items
    {
        get
        {
            return items;
        }
        set
        {
            if (items != value)
            {
                items = value;
                RaisePropertyChanged("Items");
            }
        }
    }

    public string Name
    {
        get
        {
            return name;
        }
        set
        {
            if (name != value)
            {
                name = value;
                RaisePropertyChanged("Name");
            }
        }
    }

    ...... other variables .....

    public event PropertyChangedEventHandler PropertyChanged;
    void RaisePropertyChanged(string prop)
    {
        if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(prop)); }
    }
}

}

和 View 模型
namespace MiningCalc.ViewModel
{
class ViewModelPlayer : INotifyPropertyChanged
{
    private decimal oreMineTotal;
    private decimal oreTransportTotal;
    private ObservableCollection<Player> players;

    public ObservableCollection<Player> Players
    {
        get
        {
            return players;
        }
        set
        {
            players = value;
            OnPropertyChanged("Players");
            OnPropertyChanged("OreMineTotal"); //not working
            OnPropertyChanged("OreTransportTotal"); // not working
        }
    }

    public ViewModelPlayer()
    {
        players = new ObservableCollection<Player>();
        players.CollectionChanged += OnCollectionChanged;
        LoadLogCommand = new RelayCommand(LoadLog, LoadLog_CanExecute);
    }

    private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        //System.Windows.MessageBox.Show("Firing");
        OnPropertyChanged("OreMineTotal");
        OnPropertyChanged("OreTransportTotal");
    }

    public decimal OreMineTotal
    {
        get
        {
            oreMineTotal = Players.Where(x => x.Role == 0).Sum(a => decimal.Parse(a.Mass, NumberStyles.Any));
            return oreMineTotal;
        }
        set
        {
            oreMineTotal = value;
            OnPropertyChanged("OreMineTotal");
        }
    }


    public decimal OreTransportTotal
    {
        get
        {
            oreTransportTotal = Players.Where(x => x.Role == 1).Sum(a => decimal.Parse(a.Mass, NumberStyles.Any));
            return oreTransportTotal;
        }
        set
        {
            oreTransportTotal = value;
            OnPropertyChanged("OreTransportTotal");
        }
    }
    ...........

最佳答案

每当一个项目被添加到您的 ObservableCollection ,您需要添加一个 PropertyChanged该项目的事件处理程序并使用它来更新您的总数。

每当从您的 ObservableCollection 中删除项目时,您需要删除该处理程序。

每当您的 ObservableCollection 中的项目被替换时,您需要从旧项目中删除处理程序并将处理程序添加到新项目。

这通常在 CollectionChanged 内部实现。处理程序在 NotifyCollectionChangedEventArgs 的更改类型枚举上使用 switch 语句.

目前,您只跟踪集合本身的更改。您还需要监控项目的更改:)

除此之外,这里没有 MVVM 问题。除了上面的代码之外,您的代码是专家级 MVVM。没有进一步的 MVVM 方法来增强您的代码。

关于c# - WPF - 更改对象属性时通知 ViewModel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44852686/

相关文章:

c# - 如何正确继承和隐藏基方法

javascript - 如何根据下拉框中选择的项目 ID 将文本框(循环)的值从 View 传递到 Controller ?

c# - 如何在同一解决方案中使用来自多个项目的 NLog

c# - 使用 Process.Start 启动 WPF 应用程序

android - 如何在 ViewModel Android 中获取 Activity 上下文?

c# - 'call command on property change' 功能应该去哪里?

c# - 在 SSMS 中运行良好的 SQL 查询在 ASP.NET 中运行非常慢

c# - 对字符串列表(门牌号)进行排序

c# - 使用 wpf 在列表框中绑定(bind)字典的键和值

ios - ReactiveCocoa 和 MVVM 混淆