具有相同名称的属性的 INotifyPropertyChanged

INotifyPropertyChanged with Properties that have the same name

我正在开发一个表示数据的系统。在其中,我们使用实现 INotifyPropertyChanged.

的模板化接口
public interface IScalar<T> : ISignal, INotifyPropertyChanged
{
    void Check(T value);

    /// <summary>
    /// Formats the specified value based on the item's formatting
    /// characteristics. Will throw an exception if the specified value
    /// could not be properly converted to the underlying type.
    /// </summary>
    /// <param name="value">Value to format.</param>
    /// <returns>Formatted value.</returns>
    string Format(T value);

    T Value { get; set; }
    string Units { get; set; }
}

我们最终得到一个实现了 IScalar<double>IScalar<string> 的 class。有没有办法确保触发正确的 PropertyChanged 事件?它使用 属性 名称的字符串表示形式。因为我有两个同名的属性,所以我不能保证会触发正确的事件。我们希望 WPF 中的网格绑定到 IScalar

列表

您的数据上下文中不能有两个同名的属性。 如果这样做,您将遇到反映歧义的编译错误。

请记住,您的 source 是您的数据上下文。

此外,数据绑定系统依赖于 sourcepath 来执行数据绑定。

您不能隐式实现具有两个不同类型参数的泛型接口。您必须至少明确一项。在这里,您可以看到 class 的示例实现。如您所见,您可以绑定到 StringValueDoubleValue:

public class Both : IScalar<string>, IScalar<double>
{
    public string StringValue { get; set; }

    string IScalar<string>.Value
    {
        get
        {
            return StringValue;
        }
        set
        {
            this.StringValue = value;
        }
    }

    public double DoubleValue { get; set; }

    double IScalar<double>.Value
    {
        get
        {
            return DoubleValue;
        }
        set
        {
            DoubleValue = value;
        }
    }

    // other methods and properties left out
}

当您需要引发 PropertyChanged 时,您可以引发 StringValueDoubleValue 的事件。

除了 Scott 的正确答案之外,您可能还想通过传入字符串来避免调用 PropertyChanged 方法。方法如下:

protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
    var handler = PropertyChanged;
    if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}

在 System.runtime.compilerservices 程序集中找到的 class CallerMemberName 属性现在支持使用 member/method 名称的 INPC。

您可以阅读更多相关信息 here

优点: 它允许您轻松地建立一个基 class 一劳永逸地处理仅基于方法名称的所有通知。 setter 方法只有这行代码:

OnPropertyChanged();