llo*_*mas 15 c# wpf binding mvvm inotifypropertychanged
我有一个Person类:
public class Person : INotifyPropertyChanged
{
private string _name;
public string Name{
get { return _name; }
set {
if ( _name != value ) {
_name = value;
OnPropertyChanged( "Name" );
}
}
private Address _primaryAddress;
public Address PrimaryAddress {
get { return _primaryAddress; }
set {
if ( _primaryAddress != value ) {
_primaryAddress = value;
OnPropertyChanged( "PrimaryAddress" );
}
}
//OnPropertyChanged code goes here
}
Run Code Online (Sandbox Code Playgroud)
我有一个Address类:
public class Address : INotifyPropertyChanged
{
private string _streetone;
public string StreetOne{
get { return _streetone; }
set {
if ( _streetone != value ) {
_streetone = value;
OnPropertyChanged( "StreetOne" );
}
}
//Other fields here
//OnPropertyChanged code goes here
}
Run Code Online (Sandbox Code Playgroud)
我有一个ViewModel:
public class MyViewModel
{
//constructor and other stuff here
private Person _person;
public Person Person{
get { return _person; }
set {
if ( _person != value ) {
_person = value;
OnPropertyChanged( "Person" );
}
}
}
Run Code Online (Sandbox Code Playgroud)
我有一个视图,其中包含以下行:
<TextBox Text="{Binding Person.Name, Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged />
<TextBox Text="{Binding Person.Address.StreetOne, Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged />
Run Code Online (Sandbox Code Playgroud)
视图加载时,两个值都显示在文本框中.
将OnPropertyChanged( "Person" )在MyViewModel 中触发对第一个文本框的更改.大.
对MyViewModel内部的第二个文本框的更改("Person.Address.StreetOne")不会触发OnPropertyChanged( "Person" ).这意味着它不会调用Person对象的SET方法.不是很好.有趣的是,调用了Address类中的StreetOne的SET方法.
如何在Person.Address.StreetOne更改时调用ViewModel中的Person对象的SET方法?
我是否需要展平我的数据,以便SteetOne在Person内部而不是Address?
谢谢!
And*_*lon 15
虽然向ViewModel添加"传递"属性是一个很好的解决方案,但它很快就会变得难以维持.标准替代方法是传播更改,如下所示:
public Address PrimaryAddress {
get => _primaryAddress;
set {
if ( _primaryAddress != value )
{
//Clean-up old event handler:
if(_primaryAddress != null)
_primaryAddress.PropertyChanged -= AddressChanged;
_primaryAddress = value;
if (_primaryAddress != null)
_primaryAddress.PropertyChanged += AddressChanged;
OnPropertyChanged( "PrimaryAddress" );
}
void AddressChanged(object sender, PropertyChangedEventArgs args)
=> OnPropertyChanged("PrimaryAddress");
}
}
Run Code Online (Sandbox Code Playgroud)
现在,更改通知将从地址传播到人员.
编辑:将处理程序移动到c#7本地函数.
如果要调用viewmodel SET,可以创建一个street属性
public class MyViewModel
{
//constructor and other stuff here
public string Street{
get { return this.Person.PrimaryAddress.StreetOne; }
set {
if ( this.Person.PrimaryAddress.StreetOne!= value ) {
this.Person.PrimaryAddress.StreetOne = value;
OnPropertyChanged( "Street" );
}
}
}
Run Code Online (Sandbox Code Playgroud)
XAML
<TextBox Text="{Binding Street, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged />
Run Code Online (Sandbox Code Playgroud)
但这种解决方案有其缺点.我在我的项目中与Reeds一起回答
当Person.Address.StreetOne更改时,如何获取ViewModel内部的Person对象的SET方法?
为什么要这样做?它不是必需的-您只需要StreetOne触发属性更改事件即可。
我是否需要拼合数据,以便SteetOne位于Person内部而不是Address?
如果您想实际触发该事件,则无需使其变平(尽管这是一个选择)。您可以在Person类中订阅Address的PropertyChanged事件,并在Person更改时在“ Address”事件中引发该事件。但是,这不是必需的。
| 归档时间: |
|
| 查看次数: |
9547 次 |
| 最近记录: |