2

我有一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.
    }
}

如果客户名称自其值类型以来发生更改,我可以将标志 (IsCustomerNameModified) 设置为 true。但无法检测到引用类型中所做的更改。

有人可以帮忙吗?

4

5 回答 5

3

此类问题通常通过更改通知系统处理。请参阅本文:如何:实现属性更改通知

片段:

  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));
      }
  }

使用此模式将帮助您避免设置标志或其他此类机制的需要。

于 2013-03-26T14:36:13.767 回答
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属性(如果对象的引用真的改变了,我之前的答案会奏效)

于 2013-03-26T14:39:25.357 回答
0

Paul 是正确的,您需要实施 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");
            }
        }
    }
于 2013-03-26T14:42:51.453 回答
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() ) ;
}
于 2013-03-26T14:43:06.487 回答
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.
    }
}
于 2013-03-26T14:56:43.580 回答