【问题标题】:Update an object Property based on other properties根据其他属性更新对象属性
【发布时间】:2019-05-28 15:53:45
【问题描述】:

我正在尝试根据其他 2 个属性的值更新属性。

我在这里使用INotifyPropertyChanged

所以基本上我有 3 个属性 ABC。我正在更新的属性是C,这里基于AB。我能够从AB 更新C 的属性值。所以属性C 将是属性AB (C = A + B) 的附加值。当从AB 传递一个值时,它可以正常工作,但是当传递来自两个属性的值时,它只从传递的最后一个属性值中获取值。我知道当传递每个属性的值时,我需要增加 C 的值。但是实现这一目标的最佳方法是什么?

这是我的代码:

private int? _a;
public int? A
{
   get => _a;
   set
   {
       _a = value;
       OnPropertyChanged($"A");
       C = _a;
   }
 }

private int? _b;
public int? B
{
    get => _b;
    set
    {
       _b = value;
       OnPropertyChanged($"B");
       C = _b;
    }
 }

 private int? _c;
 public int? C
 {
    get => _c;
    set
    {
       _c = value;
    }
 }

 public event PropertyChangedEventHandler PropertyChanged;

 [NotifyPropertyChangedInvocator]
 protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
 {
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
 }

更新

对不起,上面的混乱,基本上我试图更新属性C的值,当属性AB通过时。所以属性C 将是属性AB (C = A + B) 的附加值。希望这能消除困惑?

【问题讨论】:

  • 如果您为 x 分配一系列值,x 将始终具有您分配的最后一个值。应该计算C还是什么?你说“我知道当每个属性的值被传递时我需要增加 C 的值。” -- 然后编写代码,“当每个属性的值被传递时”将增加值 C(我们无法帮助你引用引用的部分,因为我们不知道它的含义)。在需要更新 C 时执行任何计算以确定 C 的值,每次计算结果发生变化时执行它们。
  • 您的示例代码没有任何意义。 C 始终是 A 或 B 的值(以最后更新的为准)。你想用它做什么?
  • 例如,如果 C 始终是 A 和 B 的总和,则在 A 和 B 的设置器中,添加以下内容:@ 987654344@如果是产品,C = A * B;和C的setter应该调用OnPropertyChanged("C");
  • “基于AB 的值”...“基于”是什么意思?添加?减去?相乘?
  • 你不能只拥有C 属性return _a + _b 吗?意图(或问题)仍不清楚。

标签: c# winforms inotifypropertychanged


【解决方案1】:

鉴于上述说明,您要做的是:

private int? _a;
public int? A
{
   get => _a;
   set
   {
       if (value.HasValue != _a.HasValue || value.GetValueOrDefault(0) != _a.GetValueOrDefault(0))
       {
          _a = value;
          OnPropertyChanged();
          OnPropertyChanged(nameof(C));
       }
   }
 }

private int? _b;
public int? B
{
    get => _b;
    set
    {
       if (value.HasValue != _b.HasValue || value.GetValueOrDefault(0) != _b.GetValueOrDefault(0))
       {
          _a = value;
          OnPropertyChanged();
          OnPropertyChanged(nameof(C));
       }
    }
 }

 public int? C
 {
    get => A + B;
 }

 public event PropertyChangedEventHandler PropertyChanged;

 [NotifyPropertyChangedInvocator]
 protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
 {
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
 }

【讨论】:

  • 或使用OnPropertyChanged(nameof(C));
  • @stuartd 打败了我 :)
  • @Kevin 您只想确保每当 C 的值发生变化时都会调用 OnPropertyChanged(nameof(C))。因此,找出导致 C 值变化的原因,并将其放在那里。如果 C 有一个 setter,请在 Steve 向您展示的 if 语句内的 setter 中调用 OnPropertyChanged(nameof(C))(并且永远不要在该 setter 之外设置 _c)。如果 C => A + B;,那么 A 和 B 的 setter 会改变 C 的值,所以你想把 OnPropertyChanged(nameof(C)) 放在这两个 setter 中。
  • @Ed,OnPropertyChanged 中的参数提示 [CallerMemberName] 会自动填充导致更改的函数/属性名称,因此 C 的设置器(如果存在)不需要 nameof 位(您可能知道,但为了 OP 的利益)。
  • @JuanR,直接访问除 getter 和 setter 之外的其他地方的支持变量被认为是不好的做法。如果在读取或更改值时更改代码以触发其他操作怎么办?这两个调用首先是说“此属性已更改”,然后是“依赖于此值的此其他属性也必须已更改”
猜你喜欢
  • 1970-01-01
  • 2018-03-01
  • 1970-01-01
  • 2020-12-05
  • 1970-01-01
  • 1970-01-01
  • 2017-03-22
  • 1970-01-01
  • 2015-02-18
相关资源
最近更新 更多