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

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 に答える
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 に答える