我是 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/