在类中使用INotifyPropertyChanged

时间:2012-11-27 06:35:08

标签: c# wpf

C#允许创建如下属性:

public string SomeRandomText
{
    get; set;
}

框架处理此属性的支持变量的创建。我怎么能拥有这样的财产并仍然有变更通知?

这是否允许在实现INotifyPropertyChanged的类中使用?

public string SomeRandomTextBeingNotified
{
    get;
    set
    {
        NotifyPropertyChanged("SomeRandomTextBeingNotified");
    }
}

5 个答案:

答案 0 :(得分:3)

尝试使用此功能时,无法使用自动属性。您需要创建一个后备存储:

private string _someRandomText;
public string SomeRandomText {
    get { return _someRandomText; }
    set 
    {
        _someRandomText = value;
        NotifyPropertyChanged("SomeRandomText");
    }
}

答案 1 :(得分:1)

要使代码看起来更清晰,可以使用INotifyPropertyChanged的属性。

Easy usage of INotifyPropertyChanged with Property-Attribute

看看这个Use of Attributes... INotifyPropertyChanged

答案 2 :(得分:1)

实际上你可以,但你基本上需要在C#编译器后更改字节码。

这可能听起来像是很多工作,但这是PostSharp包含的更简单的后处理步骤之一。

http://www.sharpcrafters.com/solutions/notifypropertychanged

http://www.sharpcrafters.com/blog/post/Recording-Automate-INotifyPropertyChanged-with-Karol-Waledzik-from-Internetium.aspx

可以使用更多功能;)

否则请注意

enter code here在此输入代码`NotifyPropertyChanged(“SomeRandomTextBeingNotified”);

是错误的代码。我在一个字段更新方法中做了所有这些:

set 
{
    OnUpateField (ref _someRandomText, value);
}

更新方法完成所有操作 - 检查是否相等(您不希望在新值=旧值时触发),然后根据需要触发更新。它通过编译器自动设置的调用方法第三个参数获取属性名称。替代方案是使用LINQ语句(ref someRandomText,value,this-> SomeRandomText)。我永远不会喜欢那里没有重构重命名的字符串;)

答案 3 :(得分:1)

如果你没有基类,那么像这样的东西是非常灵活的:

public class NotificationObject : INotifyPropertChanged
{
    private readonly Dictionary<string, object> Properties = new Dictionary<string, object>();

    public event PropertyChangedEventHandler PropertyChanged;

    protected TType Get<TType>(string propertyName)
    {
        object value;
        return Properties.TryGetValue(propertyName, out value) ? (TType)value : default(TType);
    }

    protected void Set<TType>(TType value, string propertyName, params string[] dependantPropertyNames)
    {
        Properties[propertyName] = value;
        OnPropertyChanged(propertyName);
        if (dependantPropertyNames != null)
        {
            foreach (string dependantPropertyName in dependantPropertyNames)
            {
                OnPropertyChanged(dependantPropertyName);
            }
        }
    }

    protected void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArts(propertyName));
        }
    }
}

可以这样使用:

public SomeObjectThatNeedsToNotifySomething : NotificationObject
{
    public int SomeValue
    {
        get { return Get<int>("SomeValue"); }
        set { Set<int>(value, "SomeValue", "SomeAggregateValue"); }
    }

    public int SomeOtherValue
    {
        get { return Get<int>("SomeOtherValue"); }
        set { Set<int>(value, "SomeOtherValue", "SomeAggregateValue"); }
    }

    public int SomeAggregateValue
    {
        get { return SomeValue + SomeOtherValue; }
    }
}

如果您已经有一个基类并且需要实现INotifyPropertyChanged接口,那么@Rob是正确的,提供一个支持字段并触发事件。

答案 4 :(得分:1)

没有半自动属性。然而,有很多方法可以实现不需要繁琐的命令式代码的INotifyPropertyChanged。

1)之前提到过:PostSharp,一个面向方面的商业项目。

2)创建Castle DynamicProxy解决方案。可以找到一个样本here,实际上还有很多其他的样本。

值得在通用解决方案中投入一些时间,样板代码可能会在一段时间后变得烦恼并且容易出错。