Wpf 当一组属性之一发生更改时在代码中生成字符串
我正在寻求有关如何在多处房产发生变化时获得通知的建议 例如,假设我想将控件的文本绑定到WPF ViewModel中的FullAddress属性,只要一组属性(如StreetNumber、StreetName、郊区、邮政编码等)发生更改,我就可以动态计算该属性Wpf 当一组属性之一发生更改时在代码中生成字符串,wpf,binding,properties,Wpf,Binding,Properties,我正在寻求有关如何在多处房产发生变化时获得通知的建议 例如,假设我想将控件的文本绑定到WPF ViewModel中的FullAddress属性,只要一组属性(如StreetNumber、StreetName、郊区、邮政编码等)发生更改,我就可以动态计算该属性 我想我需要将显示控件绑定到FullAddress属性,但是如何让它在一个依赖属性更改时自动更新?我可以将属性的codebehind绑定到同一ViewModel上的多个其他属性吗?如果是,怎么做?有更好的方法吗?假设您的类实现了INotify
我想我需要将显示控件绑定到FullAddress属性,但是如何让它在一个依赖属性更改时自动更新?我可以将属性的codebehind绑定到同一ViewModel上的多个其他属性吗?如果是,怎么做?有更好的方法吗?假设您的类实现了INotifyPropertyChanged,那么您可以在任何属性设置器中进行通知。例如
#region Implementation of INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
Address.BeginEdit();
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
public string FirstLine
{
get { return firstLine; }
set
{
firstLine = value;
OnPropertyChanged("FirstLine");
OnPropertyChanged("FullAddress");
}
}
public string SecondLine
{
get { return secondLine; }
set
{
secondLine= value;
OnPropertyChanged("SecondLine");
OnPropertyChanged("FullAddress");
}
}
public string FullAddress
{
get { return firstLine + secondLine; }
}
假设您的类实现了INotifyPropertyChanged,那么您可以在任何属性设置器中进行通知。例如
#region Implementation of INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
Address.BeginEdit();
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
public string FirstLine
{
get { return firstLine; }
set
{
firstLine = value;
OnPropertyChanged("FirstLine");
OnPropertyChanged("FullAddress");
}
}
public string SecondLine
{
get { return secondLine; }
set
{
secondLine= value;
OnPropertyChanged("SecondLine");
OnPropertyChanged("FullAddress");
}
}
public string FullAddress
{
get { return firstLine + secondLine; }
}
试着这样做:
public class Address : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string address1;
public string Address1
{
get { return address1; }
set
{
address1 = value;
OnPropertyChanged("Address1");
OnPropertyChanged("FullAddress");
}
}
private string address2;
public string Address2
{
get { return address2; }
set
{
address2 = value;
OnPropertyChanged("Address2");
OnPropertyChanged("FullAddress");
}
}
private string town;
public string Town
{
get { return town; }
set
{
town = value;
OnPropertyChanged("Town");
OnPropertyChanged("FullAddress");
}
}
public string FullAddress
{
get { return string.Format("{0}, {1}, {2}", address1, address2, town); }
}
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
试着这样做:
public class Address : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string address1;
public string Address1
{
get { return address1; }
set
{
address1 = value;
OnPropertyChanged("Address1");
OnPropertyChanged("FullAddress");
}
}
private string address2;
public string Address2
{
get { return address2; }
set
{
address2 = value;
OnPropertyChanged("Address2");
OnPropertyChanged("FullAddress");
}
}
private string town;
public string Town
{
get { return town; }
set
{
town = value;
OnPropertyChanged("Town");
OnPropertyChanged("FullAddress");
}
}
public string FullAddress
{
get { return string.Format("{0}, {1}, {2}", address1, address2, town); }
}
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
我认为这里唯一的选择是让类的对象订阅它们自己的INPC事件,并自动更改它们的依赖属性。工作流程如下所示:
public class Address : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string address1;
public string Address1
{
get { return address1; }
set
{
address1 = value;
OnPropertyChanged("Address1");
OnPropertyChanged("FullAddress");
}
}
private string address2;
public string Address2
{
get { return address2; }
set
{
address2 = value;
OnPropertyChanged("Address2");
OnPropertyChanged("FullAddress");
}
}
private string town;
public string Town
{
get { return town; }
set
{
town = value;
OnPropertyChanged("Town");
OnPropertyChanged("FullAddress");
}
}
public string FullAddress
{
get { return string.Format("{0}, {1}, {2}", address1, address2, town); }
}
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
FullAddress
的从属属性已更改,并更新FullAddress
值FullAddress
setter触发自己的INPC事件FullAddress
已更改并更新UIclass NotificationExample : INotifyPropertyChanged
{
private string firstName;
private string lastName;
public event PropertyChangedEventHandler PropertyChanged;
public string FirstName
{
get { return this.firstName; }
set
{
this.firstName = value;
this.OnPropertyChanged("FirstName");
}
}
public string LastName
{
get { return this.lastName; }
set
{
this.lastName = value;
this.OnPropertyChanged("LastName");
}
}
public string FullName
{
get { return string.Format("{0} {1}", this.firstName, this.lastName); }
}
public NotificationExample()
{
this.PropertyChanged += this.NotifyIfFullNameChanged;
}
private void OnPropertyChanged(string propertyName)
{
var handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
private void NotifyIfFullNameChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "FirstName" || e.PropertyName == "LastName")
{
this.OnPropertyChanged("FullName");
}
}
}
我认为这里唯一的选择是让类的对象订阅它们自己的INPC事件,并自动更改它们的依赖属性。工作流程如下所示:
public class Address : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string address1;
public string Address1
{
get { return address1; }
set
{
address1 = value;
OnPropertyChanged("Address1");
OnPropertyChanged("FullAddress");
}
}
private string address2;
public string Address2
{
get { return address2; }
set
{
address2 = value;
OnPropertyChanged("Address2");
OnPropertyChanged("FullAddress");
}
}
private string town;
public string Town
{
get { return town; }
set
{
town = value;
OnPropertyChanged("Town");
OnPropertyChanged("FullAddress");
}
}
public string FullAddress
{
get { return string.Format("{0}, {1}, {2}", address1, address2, town); }
}
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
FullAddress
的从属属性已更改,并更新FullAddress
值FullAddress
setter触发自己的INPC事件FullAddress
已更改并更新UIclass NotificationExample : INotifyPropertyChanged
{
private string firstName;
private string lastName;
public event PropertyChangedEventHandler PropertyChanged;
public string FirstName
{
get { return this.firstName; }
set
{
this.firstName = value;
this.OnPropertyChanged("FirstName");
}
}
public string LastName
{
get { return this.lastName; }
set
{
this.lastName = value;
this.OnPropertyChanged("LastName");
}
}
public string FullName
{
get { return string.Format("{0} {1}", this.firstName, this.lastName); }
}
public NotificationExample()
{
this.PropertyChanged += this.NotifyIfFullNameChanged;
}
private void OnPropertyChanged(string propertyName)
{
var handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
private void NotifyIfFullNameChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "FirstName" || e.PropertyName == "LastName")
{
this.OnPropertyChanged("FullName");
}
}
}
您可以使用也可以不使用FullAddress属性编辑:
如果只需要显示完整地址,可以使用
StringFormat
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0}, {1}">
<Binding Path="City"/>
<Binding Path="Street"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
如果您希望允许用户编辑整个地址字符串,然后将其拆分为多个部分,则需要实现接口您可以使用,也可以不使用FullAddress属性编辑:
如果只需要显示完整地址,可以使用
StringFormat
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0}, {1}">
<Binding Path="City"/>
<Binding Path="Street"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
如果您希望允许用户编辑整个地址字符串,然后将其拆分为多个部分,那么您需要实现接口David感谢非常快速的响应和代码,这非常有意义。非常感谢!David感谢您的快速响应,感谢代码,这很有意义。非常感谢!迪安:我也感谢你的快速回答,伟大的人都有相同的想法。显然,你的回答和第一个答案之间的一致给我留下了深刻的印象。我会研究这段代码。我想我们是在同一时间发布的,他们都是正确的。遗憾的是,我似乎还不能投票支持任何帖子,对不起,这是我第一次在StackOverflow上发表文章。迪安,我也感谢你的快速回答,伟大的人都有同感。显然,你和第一个答案之间的一致给我留下了深刻的印象。我会研究这段代码。我想我们是在同一时间发布的,他们都是正确的。遗憾的是,我似乎还不能投票支持任何帖子,对不起,这是我第一次在StackOverflow上发布。谢谢Jon,另一个快速回答。我花了很长时间才明白这一点。我有点理解,但在步骤4中,INPC订阅如何知道FullAddress属性依赖哪些属性?我假设Object是指包含FullAddress和从属属性的类的实例,对象本身是否调用整个对象上的PropertyChanged而不是一个属性?INPC订户将是类中的私有方法。它将“知道”FullAddress依赖于什么,因为您知道它(如果e.PropertyName==“StreetAddress”等)。目标就是你所说的。PropertyChanged始终在特定属性上调用,不能在“整个对象”上调用它。要使其正常工作,FullAddress及其相关属性都需要从其setter中调用PropertyChanged。谢谢!我就快到了。。。如果我理解正确,当你说“对象订阅它自己的INPC”时,你是说在FullAddress所依赖的每个属性中,我为该属性调用PropertyChanged,但也为FullAddress属性调用OnPropertyChanged,如代码示例所示?或者,是否有一种方法可以让对象从WPF依赖属性后端获得对象内的某些内容已更改的通知?抱歉,我不确定私有方法和INPC订阅之间的链接。检查上面的代码,这就是我的意思(请参阅构造函数和
notifyfullnamechanged
)。这与迪恩·乔克的答案基本相同,实现方式略有不同。明白了!谢谢你的坚持,现在说得通了。很好的代码。谢谢Jon,另一个快速回答。我花了很长时间才明白这一点。我有点理解,但在步骤4中,INPC订阅如何知道FullAddress属性依赖哪些属性?我假设Object是指包含FullAddress和依赖属性的类的实例,对象本身是否在整个对象上调用PropertyChanged,而不是只调用一个适当的属性