【问题标题】:Fire PropertyChanged for derived properties when parent property changes父属性更改时为派生属性触发 PropertyChanged
【发布时间】:2019-02-12 14:04:43
【问题描述】:

基本上,我有一个高度为 PX 和 MM 的图像(用于打印)。作为“派生”属性,我有 µm / px 值:

public int HeightPX { get { return _HeightPX; } private set { _HeightPX = value; RaisePropertyChanged(); }
public int HeightMM { get { return _HeightMM; } set { _HeightMM = value; RaisePropertyChanged(); }
public double MUpPX { get {return HeightPX != 0 ?  HeightMM * 1000 / HeightPX :  0; } }

所有这些都通过绑定显示在 WPF 文本框中。

Text="{Binding ImageThing.MUpPX, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"

但是,当更改 HeightPXHeightMM 时,MUpPX 显然会更改,但不会触发 PropertyChanged 事件,因此不会在 GUI 中更新。

我怎样才能做到这一点?我可以在MUpPX 中以某种方式监听HeightPropertyChanged 事件,然后触发相应的事件吗?

我想避免从Height 触发事件,因为可能/将会有其他派生属性,如果我必须处理“父”中的每个派生属性,这将不是一个非常干净的抽象。 .

【问题讨论】:

  • 看看this question。我在那里提供了一个答案,其中包含基于属性的方法的示例。

标签: c# wpf data-binding inotifypropertychanged


【解决方案1】:

您应该在想要更新 UI 时致电RaisePropertyChanged(nameof(MUpPX))

如果您不想在 Height* 属性的设置器中执行此操作,您可以在您的 RaisePropertyChanged 方法中执行此操作,例如:

public void RaisePropertyChanged([CallerMemberName]string caller = null)
{
    if (PropertyChanged != null)
    {
        PropertyChanged.Invoke(this, new PropertyChangedEventArgs(caller));
        if (caller == nameof(HeightPX) || caller == nameof(HeightMM))
        {
            PropertyChanged.Invoke(this, new PropertyChangedEventArgs(nameof(MUpPX)));
        }
    }
}

【讨论】:

  • 所以没有办法将所有内容保存在一个地方吗?我的意思是,这没关系,但我仍然希望将MUpPX 的所有代码保存在一个地方。是否有可能以某种方式监听来自属性本身的事件?
  • 嗯,不。属性只是一种读取、写入或计算字段值的机制。它不是“在一个地方”设置的。不过,此解决方案确实将刷新属性的逻辑保留在一个地方。
  • 好的,谢谢。您的解决方案有效,所以我会接受。不是完全优雅,但如果不可能,那就不可能。而且比在每个 setter 中调用 PropertyChanged 更好。
猜你喜欢
  • 2011-02-08
  • 1970-01-01
  • 1970-01-01
  • 2021-08-25
  • 2011-01-26
  • 2011-11-28
  • 2014-04-08
  • 1970-01-01
  • 2011-02-13
相关资源
最近更新 更多