在不添加私有变量的情况下引发propertychanged事件

时间:2011-10-21 08:48:33

标签: c#

我有一个看起来像这样的房产。

public int NumberOfElephants { get; set; }

此属性位于observablecollection中,并且必须通知另一个属性它已更改。

我将如何做以下

public int NumberOfElephants { get; set { OnPropertyChanged("totalAnimals"); }

没有代码需要像这样

private int _numberOfElephants;
public int NumberOfElephants { 
    get { 
        return _numberOfElephants; 
    } 

    set { 
        _numberOfElephants = value; 
        OnPropertyChanged("totalAnimals"); 
    } 
}

5 个答案:

答案 0 :(得分:8)

你没有。你不能。

当属性微不足道时,自动实现属性工作 - 当get / set超出“返回变量值”或“设置变量值”时不需要代码。你可以通过重新格式化来缩短它,当然......我会把它写成:

private int numberOfElephants;
public int NumberOfElephants {
    get { return numberOfElephants; }

    set {
        _numberOfElephants = value; 
        OnPropertyChanged("totalAnimals"); 
    } 
}

实际上,我会使用“自行打开支架”作为开始设置和属性的开始,但我保留了你喜欢的风格。但是在单行上使用“单个表达式get / set实现”可以使具有大量属性的类更加清晰。

答案 1 :(得分:4)

作为Jon的答案的替代方案,您可以通过IL编织获得可以执行此操作的工具,例如NotifyPropertyWeaver,也可以通过VS Gallery

作为工具使用

根据他们的doco on Attributes,对于您的样本,您应该能够拥有以下内容:

[NotifyProperty(AlsoNotifyFor = new[] { "TotalAnimals" })]
public int NumberOfElephants { get; set; }

public int TotalAnimals { get; set; }

但是,根据以下网站上的示例,根据TotalAnimals的实施情况,可能不需要这样做:

  

您的代码

public class Person : INotifyPropertyChanged {
    public event PropertyChangedEventHandler PropertyChanged;

    public string GivenNames { get; set; }
    public string FamilyName { get; set; }

    public string FullName
    {
        get
        {
            return string.Format("{0} {1}", GivenNames, FamilyName);
        }
    }

}
     

汇编了什么

public class Person : INotifyPropertyChanged {

    public event PropertyChangedEventHandler PropertyChanged;

    string givenNames;
    public string GivenNames
    {
        get { return givenNames; }
        set
        {
            if (value != givenNames)
            {
                givenNames = value;
                OnPropertyChanged("GivenNames");
                OnPropertyChanged("FullName");
            }
        }
    }

    string familyName;
    public string FamilyName
    {
        get { return familyName; }
        set 
        {
            if (value != familyName)
            {
                familyName = value;
                OnPropertyChanged("FamilyName");
                OnPropertyChanged("FullName");
            }
        }
    }

    public string FullName
    {
        get
        {
            return string.Format("{0} {1}", GivenNames, FamilyName);
        }
    }

    public virtual void OnPropertyChanged(string propertyName)
    {
        var propertyChanged = PropertyChanged;
        if (propertyChanged != null)
        {
            propertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

答案 2 :(得分:3)

扩展@jeffora的答案

使用NotifyPropertyWeaver你可以写这个

public class Animals: INotifyPropertyChanged
{
    public int NumberOfElephants { get; set; }
    public int NumberOfMonkeys { get; set; }

    public int TotalAnimals
    {
        get
        {
            return NumberOfElephants + NumberOfMonkeys;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

这将被编译

public class Animals : INotifyPropertyChanged
{
    int numberOfElephants;
    int numberOfMonkeys;

    public int NumberOfElephants
    {
        get { return numberOfElephants; }
        set
        {
            numberOfElephants = value;
            OnPropertyChanged("TotalAnimals");
            OnPropertyChanged("NumberOfElephants");
        }
    }

    public int NumberOfMonkeys
    {
        get { return numberOfMonkeys; }
        set
        {
            numberOfMonkeys = value;
            OnPropertyChanged("TotalAnimals");
            OnPropertyChanged("NumberOfMonkeys");
        }
    }


    public int TotalAnimals
    {
        get { return NumberOfElephants + NumberOfMonkeys; }
    }

    public virtual void OnPropertyChanged(string propertyName)
    {
        var propertyChanged = PropertyChanged;
        if (propertyChanged != null)
        {
            propertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

答案 3 :(得分:1)

使用像PostSharp这样的工具,您可以编织属性以创建锅炉板代码。此外,您不必实现INotifyPropertyChanged,PostSharp可以为您完成。

请参阅此blog post

答案 4 :(得分:0)

我会在C#6中使用它

private int numberOfElephants;
public int NumberOfElephants {
    get => numberOfElephants; 

    set {
        _numberOfElephants = value; 
        OnPropertyChanged(); 
    } 
}


private void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}

这需要

using System.Runtime.CompilerServices;