2010-03-17 7 views
2

개체에 바인딩되는 양식이 있고 사용자가 양식을 벗어나려고 할 때 양식의 내용이 변경된 경우이를 경고하고 저장하라는 메시지를 표시하려고합니다. 내 질문에 바인딩 된 개체의 모든 클래스에 대해 IComparar를 구현하지 않고이 작업을 수행 할 수있는 방법이 있습니까? 양식을로드 할 때 객체를 직렬화 할 수있는 방법이 있다면 생각하고 있었고 직렬화 된 변경 객체에 대한 간단한 비교도 수행했습니다. 문자열 비교 같은 것. 이해직렬화를 사용하여 객체의 상태가 변경되었는지 확인 하시겠습니까?

희망,

감사

+0

모든 답변을 주셔서 감사합니다. IsDirty 방법을 알고 있지만이 작업을 수행 할 수있는 다른 방법이 있는지 궁금해하고 있습니다. 이제는 XML로 객체를 직렬화하면 더욱 신뢰할 수있는 방법이 될 것입니다. – sev7n

답변

0

당신이하려는 일을하기 위해서는 훨씬 간단한 방법이 있습니다 : "수정 된"깃발이나 이벤트를 사용하십시오.

필요한 경우 여러 수준의 사용자 컨트롤을 계단식으로 연결할 수 있습니다.

그런 다음 실제로 수정 사항을 확인해야하는 모든 이벤트를 후크하십시오.

public class MainForm : Form 
{ 
    private bool isDataModified; 

    public MainForm() 
    { 
     InitializeComponent(); 

     textBox1.TextChanged += DataModified; 
     textBox2.TextChanged += DataModified; 
     // etc. 
     userControl1.Modified += DataModified; 
     userControl2.Modified += DataModified; 
     // etc. 
    } 

    private void DataModified(object sender, EventArgs e) 
    { 
     isDataModified = true; 
    } 
} 

그런 다음 당신이해야 할 검사입니다 (리셋) 따라 isDataModified 플래그.

정말 많은 작업이 아니며 그래프의 모든 개체에 대해 INotifyPropertyChanged이 구현되도록하는 것보다 쉽습니다. 이 형식 일 뿐이며 오브젝트이 변경되었다는 사실을 염려하지 않으시 고 사용자이 변경되면 실제로 변경 사항을 확인하고 싶습니다.

그래, 완벽하지는 않습니다. 사용자가 무언가를 변경하고 다시 변경하더라도 데이터가 변경되었다는보고는 사소한 불편을 겪습니다. 그러나 나는 이것에 대한 불만을 실제로들은 적이 없다고 생각합니다. 그리고 직렬화를 비교 방법으로 사용하는 것은 신뢰할 만합니다. 여분의 저장 확인을 제거하려면 실제로 그래프의 모든 오브젝트에 대해 Equals 메소드를 대체하고 실제 값 동등성 조작을 구현해야합니다. 또는 오래된 그래프의 복사본을 유지하지 않으려면 체크섬 생성 함수를 사용하십시오 (충돌은 가능하지만 매우 드뭅니다).

하지만 나는 깃발을 붙잡을뿐입니다. 평등성 수표를 작성하는 길을 사기려고하지 마십시오. 실제로 자동 딥 복제 방법을 쓰는 것과 똑같습니다. 당신은 시도 할 수 있습니다. 그러나 당신이 생각해내는 것은 무엇이든 가끔 깨질 것입니다.

1

이 직렬화를 통해 2 오브젝트 트리를 비교하는 형태로, asked before했다.
대답은 신뢰할 수 없습니다. 서로 다른 일련의 텍스트/데이터를 생성하는 동일한 개체의 카운터 예제가 있습니다. 당신이 을에서 INotifyPropertyChanged 구현할 때 사람들이 사용하는 규칙적인 패턴을 따르는 경우

+0

선택한 시리얼 라이저와 같은 사운드가 손상되었습니다. 나는 "전에"그것을 보는 것에 흥미가있을 것입니다. –

+0

@marc : 편집을 참조하십시오. –

+0

@Marc Gravell : 클래스가 동등 연산과 직렬화 표현을 모두 제어 할 수있는 한 직렬 변환기가 완벽하게 작동한다고해도 클래스가 완전히 신뢰할 수는 없습니다. – Aaronaught

1

후 걸리는 모든 코드의 또 다른 몇 줄은 데이터 객체에 대해 IsDirty (또는 을 IsChanged) 플래그를 구현하는 것입니다.

public class BaseDataObject : INotifyPropertyChanged 
{ 

    public bool IsDirty 
    { 
     get { return _isDirty; } 
     protected set { _isDirty = value; } 
    } 

    protected void OnPropertyChanged(string propertyName) 
    { 
     _isDirty = true; 

     if (this.PropertyChanged != null) 
      this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 

    #region INotifyPropertyChanged Members 

    public event PropertyChangedEventHandler PropertyChanged; 

    #endregion 

    private bool _isDirty; 
} 


public class MyRealDataObject : BaseDataObject 
{ 
    public int MyIntProperty 
    { 
     get { return _myIntProperty; } 
     set 
     { 
      bool changed = _myIntProperty != value; 
      if (changed) 
      { 
       _myIntProperty = value; 
       OnPropertyChanged("MyIntProperty"); 
      } 
     } 
    } 

    private int _myIntProperty; 
} 

을 지금 신고 대상 속성 변경, 데이터 객체의 IsDirty 플래그가 설정됩니다 때마다 모든의

첫째, 기초를 구현하는 기본 클래스, 그리고 그것에서 파생되는 실제 데이터 클래스를 생성 참된. 변경 사항을 확인하려면 개체 컬렉션을 열거하고 IsDirty 플래그를 확인하기 만하면됩니다. 당신은 영리 있다면 당신은 LINQ 문을 수행 할 수 있습니다 데이터 객체가 멋진 컬렉션이 아닌 경우

bool changesMade = MyDataObjectCollection.Any(p => p.IsDirty == true).Count() > 0; 

... or .... 

bool changesMade = MyDataObjectCollection.Count(p => p.IsDirty == true) > 0; 

, 당신은 수동으로 반복해야합니다. 물론 위의 패턴은 몇 가지 다른 방법으로 리팩토링 될 수 있습니다. (어쩌면 UI 요소에 데이터 바인딩이 아니기 때문에 INotifyPropertyChanged를 사용하지 않아도 될 수 있습니다.)하지만 구현 방법에 대한 좋은 시작 예제를 제공합니다. 네가 원해.

관련 문제