C# INotifyPropertyChanged会影响派生函数吗

C# INotifyPropertyChanged会影响派生函数吗,c#,winforms,data-binding,inotifypropertychanged,C#,Winforms,Data Binding,Inotifypropertychanged,更新:我的问题最初解决了格式问题以及从多个其他属性派生的属性。我认为情况是一样的,但从法比奥斯的回答中可以看出,情况并非如此。我对这个问题做了一点修改,以明确这不仅仅是格式问题 我使用带有单向数据绑定的WinForms,并通过INotifyPropertyChanged来更新表单。但我无法确切地理解它是如何影响派生函数的。例如,假设我有一个函数,它以十进制形式返回价格: public decimal price { get { return _price; } set

更新:我的问题最初解决了格式问题以及从多个其他属性派生的属性。我认为情况是一样的,但从法比奥斯的回答中可以看出,情况并非如此。我对这个问题做了一点修改,以明确这不仅仅是格式问题

我使用带有单向数据绑定的WinForms,并通过INotifyPropertyChanged来更新表单。但我无法确切地理解它是如何影响派生函数的。例如,假设我有一个函数,它以十进制形式返回价格:

public decimal price 
{
    get { return _price; }
    set 
    { 
        // Set price and notify that it was changed
        _price = value; 
        InvokePropertyChanged(new PropertyChangedEventArgs("price");
    }
}
另一个属性负责货币代码,该代码也可以更改:

public decimal currency
{
    get { return _currency; }
    set
    {
        _currency = value;
       InvokePropertyChanged(new PropertyChangedEventArgs("currency");
    }
}
当价格或货币设置发生更改时,将调用property changed函数。但是,我希望在GUI中显示该值之前将其格式化并使用货币代码。因此,我将数据绑定到派生函数:

public string formattedPrice
{
    get { return string.Format("{0:n0} {1}", price, currency)
}
更改价格或货币将如何影响格式化价格?显然,我自己也做了一些测试,但我似乎真的找不到逻辑?InvokepropertyChanged函数的定义如下:

public event PropertyChangedEventHandler PropertyChanged;
public void InvokePropertyChanged(PropertyChangedEventArgs e)
{
    PropertyChangedEventHandler handler = PropertyChanged;
    if (handler != null) handler(this, e);
}

您只需在setter中为格式化值调用PropertyChanged

public decimal price 
{
    get { return _price; }
    set 
    { 
        _price = value; 
        InvokePropertyChanged(new PropertyChangedEventArgs("price");
        InvokePropertyChanged(new PropertyChangedEventArgs("formattedPrice");
    }
}
但是,由于格式化值更需要UIview负责,您可以使用Binding.Format事件将其移动到windows窗体端,并保持price属性不变

public decimal price 
{
    get { return _price; }
    set 
    { 
        _price = value; 
        InvokePropertyChanged(new PropertyChangedEventArgs("price");
    }
}

// In windows form
var priceBinding = new Binding("Text", sourceObject, "price", true);
priceBinding.Format += (sender, args) => 
{
    var price = (decimal)args.Value;
    args.Value = string.Format("{0:n0} EUR", price);
}

priceTextBox..DataBindings.Add(priceBinding);

更多关于

这就是我目前正在做的事情。我只是想知道是否有一种方法可以避免手动跟踪链子。在我给出的示例中,它非常简单,但在较大的程序中,链会变长,可能会出现分支,因此很难跟踪…@Noceo-check更新的答案这很酷。实际上,我的问题基于格式和从一个或多个其他属性派生的属性,因为我认为解决方案是相同的。但这至少解决了我的格式问题:-。有很多方法可以解决这个问题。有关几个选项,请参见标记的重复项。就我个人而言,我更喜欢保持我的INPC属性完全没有自定义逻辑。相反,我使用了一个基本实现,它允许setter钩住回调,并在回调中处理特定于属性的行为。然后,对于你所说的,在这样一个回调中,只需将派生属性设置为一个不幸的单词选择IMHO,因为派生在OOP中有一个特定的,完全无关的意义,它是一个新的值。是的,有更多的支持字段,但代码更简单。@PeterDuniho-我认为这个问题的具体情况更多地与格式值有关。你们提供的相关答案会把OP和未来的读者引向错误的方向。所以这很快就从零变成了火箭科学:-。我有点搞不懂你说的保持我的INPC属性完整而没有自定义逻辑是什么意思。我对C还是有点陌生,所以我必须承认我不太清楚InvokePropertyChanged函数是如何工作的。你能在代码中显示它吗?@Noceo-让我的INPC属性完全不受自定义逻辑的影响-通常意味着setter只应该做两件事:1。更新值;2.为此属性引发PropertyChanged事件。此外,还可以检查新值是否相同。所有其他逻辑都应该移到setterlike之外,比如为其他属性引发PropertyChanged事件,或者计算其他属性,或者如果需要做其他事情,则应该使用命令ICommand。没有上下文,很难建议正确的方法。至少您可以侦听该不同类中的PropertyChanged,并在基类将为您侦听的属性引发PropertyChanged时引发自己的PropertyChanged。