在Getter Only属性上的DataBinding,它可以获得2个变量

时间:2017-10-30 08:36:21

标签: c# wpf mvvm inotifypropertychanged

我有以下课程

SELECT 
   count(*) as coun,
   sum(25) as usum,
   u1.user_id 
FROM user u1
JOIN user u2 ON u2.refered = u1.user_id and u2.launch=1
GROUP BY u1.user_id
HAVING coun > 0

这些类扩展了INotifyPropertyChanged(未显示),并包含包含触发public abstract class Contact { public abstract string FullName { get; } public abstract string FullName_LastNameFirst { get; } } public class PersonContact { private string firstName; private string lastName; public override string FullName => firstName + " " + lastName; public override string FullName_LastNameFirst => lastName + ", " + firstName; } public class BusinessContact { private string name; public override string FullName => name; public override string FullName_LastNameFirst => name; } 的私有变量的公共属性。

问题是,如果我将WPF绑定到OnPropertyChangedFullName属性,那么当它们包装的任何属性发生更改时,如何更新它们。

3 个答案:

答案 0 :(得分:2)

当您更改firstName中的基础私有字段(lastNamenameBusinessContact)时,请致电

OnPropertyChanged("FullName"); 
OnPropertyChanged("FullName_LastNameFirst");

WPF数据绑定将订阅对象的PropertyChanged事件,并将侦听相应属性的更改通知。由于您的属性没有可以调用OnPropertyChanged的setter - 您需要在任何基础数据更改时显式调用它。

答案 1 :(得分:0)

你肯定有你的人的属性。如果您有ForeName属性,则可以实现它:

private string _ForeName;

public string ForeName
{
    get
    { return _ForeName; }
    set
    {
        if (_ForeName != value)
        {
            _ForeName = value;
            OnPropertyChanged(nameof(this.ForeName));
            OnPropertyChanged(nameof(this.FullName));
        }
    }
}

如您所见,如果更改了ForeName的值,将触发PropertyChanged事件。您可以使LastName属性类似。

另一个解决方案是,如果person类侦听自己的PropertyChanged:

public Person()
{
    this.PropertyChanged += this.Person_PropertyChanged;
}

private void Person_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if (e.PropertyName == nameof(LastName))
    {
        this.OnPropertyChanged(nameof(FullName));
    }
    if (e.PropertyName == nameof(ForeName))
    {
        this.OnPropertyChanged(nameof(FullName));
    }
}

如果您已生成类,并且无法更改属性设置器,则此第二个解决方案很有用。然后你可以创建一个部分类,并处理属性更改。

答案 2 :(得分:0)

Evk和lvoros的答案在技术上是正确的。

但是,您可以使用Fody ProperyChanged库(可通过Nuget获取)来编写所有这些样板代码。

写成

的课程
public class Person : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public string GivenNames { get; set; }
    public string FamilyName { get; set; }
    public string FullName => $"{GivenNames} {FamilyName}";
}

实际上会编译为

public class Person : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

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

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

    public string FullName => $"{GivenNames} {FamilyName}";

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

除直接属性包装器外,Fody还会自动为任何依赖计算属性生成OnPropertyChanged()调用。

我通常不喜欢“神奇”工作的程序,但是Fody是我的一个例子。