我有一个Customer
类,我想在用户更改Customer.CityInfo
属性的值时收到通知。
public class City
{
public long Id {get;set;}
public string Code {get;set;}
}
public class Customer
{
private City cityInfo;
private string name;
public long Id { get; set; }
public bool IsCityModified { get; set;}
public bool IsCustomerNameModified { get; set; }
public string Name
{
get{ return name;}
set
{
if(name!=value)
{
IsCustomerNameModified=true; }name=value;
}
}
}
public City CityInfo
{
get
{
if(cityInfo==null)
{
cityInfo=new City();
}
return cityInfo;
}
set{
if(this.cityInfo!=value)
{
IsCityModified =true;
}
this.cityInfo=value;
}
}
}
public ActionResult Save()
{
Customer customer=this.currentCustomerSession;
if(TryUpdateModel<Customer>(customer)){
UpdateModel<Customer>(customer)
}
if(customer.IsCustomerNameModified ){
//I am able to detect whether the customerName value has been changed in the frontend.
}
if(customer.IsCityModified){
//I am not able to detect whether the city value has been changed in the frontend.
}
}
如果Customer Name因其值类型而更改,我可以将标志(IsCustomerNameModified)设置为true。但无法检测参考类型中所做的更改。
有人可以帮忙吗?
答案 0 :(得分:3)
此类问题通常通过变更通知系统处理。请参阅此文章:How to: Implement Property Change Notification
段:
public string PersonName
{
get { return name; }
set
{
name = value;
// Call OnPropertyChanged whenever the property is updated
OnPropertyChanged("PersonName");
}
}
// Create the OnPropertyChanged method to raise the event
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
使用此模式可以帮助您避免设置标记或其他此类阴谋。
答案 1 :(得分:0)
现在我正确地理解了这个问题,我建议你做以下事情:
在public bool Changed { get; private set; }
对象中添加City
属性。
然后在对象的每个属性中,检查值是否已更改,如果已更改,则将Changed
标志置为true:
public int Id
{
{ get { return this.id } }
{
set
{
if (this.id != value) Changed = true;
this.id = value;
}
}
}
它类似于实现IPropertyChanged
接口,但是这样您确定只能检查对象是否被修改过一次。
似乎你的对象的引用没有改变,所以你只需要检查它的Changed
属性(如果对象的引用真的改变了,我的先例答案就会起作用)
答案 2 :(得分:0)
保罗是正确的,您需要实施INotifyProperty更改。这是一个简单的例子。这很简单。
public class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private int _number;
public BaseViewModel()
{
PropertyChanged += (o, p) =>
{
//this is the place you would do what you wanted to do
//when the property has changed.
};
}
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
public int Number
{
get { return _number; }
set
{
_number = value;
OnPropertyChanged("Number");
}
}
}
答案 3 :(得分:0)
我同意Paul的回答,但您甚至可能需要覆盖City类中的Equals()和GetHashCode()函数。被覆盖的函数可以检查代码和ID是否已更改。
public override bool Equals( object obj )
{
City other = obj as City;
if ( ( other != null ) && ( other.Id == this.Id ) && ( other.Code == this.Code ) )
{
return ( true );
}
return ( false );
}
public override int GetHashCode( )
{
return ( this.Id ^ this.Code.GetHashCode() ) ;
}
答案 4 :(得分:0)
您可以使用INotifyPropertyChanged,但我猜您没有将对象绑定到某个UI元素。 在这种情况下,如果仅需要知道CityInfo属性是否更改,则最简单 解决方案是提出自定义事件。
public class Customer
{
private City cityInfo;
private string name;
public long Id { get; set; }
public bool IsCityModified { get; set;}
public event Action<City> OnCityInfoChanged;
public bool IsCustomerNameModified { get; set; }
public string Name
{
get{ return name;}
set
{
if(name!=value)
{
IsCustomerNameModified=true; }name=value;
}
}
}
public City CityInfo
{
get
{
if(cityInfo==null)
{
cityInfo=new City();
}
return cityInfo;
}
set{
if(this.cityInfo ==value)
return;
IsCityModified =true;
this.cityInfo=value;
if(OnCityInfoChanged != null)
OnCityInfoChanged(value);
}
}
}
和
public ActionResult Save()
{
Customer customer=this.currentCustomerSession;
customer.OnCityInfoChanged += new Action<CityInfo>( (cityInfo) => {//Do Something with New CityInfo});
if(TryUpdateModel<Customer>(customer)){
UpdateModel<Customer>(customer)
}
if(customer.IsCustomerNameModified ){
//I am able to detect whether the customerName value has been changed in the frontend.
}
if(customer.IsCityModified){
//I am not able to detect whether the city value has been changed in the frontend.
}
}