2008-10-14 5 views
7

사용자가 GUI를 통해 기존 개체 (정확히 "필터"도메인 개체)를 편집 할 수있는 시스템에서 작업하고 있습니다. UI 힌트로서 사용자가 객체에 실제로 수정 한 경우에만 저장 버튼을 활성화하려고합니다. 나는 누군가가이 문제에 대해 어떤 경험을했는지, 그리고 가장 좋은 방법이이 문제에 접근 할 수 있는지 궁금해했다.개체 편집 및 isDirty() 플래그

도메인 객체에 isDirty() 플래그를 추가하려고 생각했습니다. 사용자가 필터 편집을 시작하면 사본을 만들어 GUI로 전달하고 사용자가 사본을 수정할 수있게합니다. 그런 다음 isDirty() 플래그를 바인딩하면 저장 버튼이 활성화/비활성화됩니다. 저장시 차이점은 원본 개체에 병합되고 유지됩니다.

덧붙여서, 사용자가 객체에 대한 변경 사항을 취소하면 어떻게 될지 생각했습니다. isDirty() 플래그는 false를 반환해야합니다. 그래서 이것을 달성하는 유일한 방법은 각 속성의 원래 값을 도메인 객체 내에 유지하는 것입니다.

아이디어가 있으십니까?

답변

3

맞음!

또한 두 가지 방법을 노출 할 수 있습니다. BeginEdit -이 방법에서는 IsDirty 플래그를 True로 표시합니다. 당신이 수정을하고 있다는 것을 의미합니다.

CancelEdit -이 메서드에서 IsDirty 플래그를 False로 다시 설정하십시오. 편집 프로세스를 중재하고 원래 상태로 되돌아 왔음을 의미합니다. 변경을 취소 할 때이 메서드를 호출합니다.

그리고 수정 사항이 지속되면 IsDirty 플래그를 False로 재설정합니다.

이 정보가 도움이되기를 바랍니다.

+0

모든 답변을 주셔서 감사합니다. 나는이 대답을 처음으로 받아 들였고 가장 큰 상향 음조를 가지고있었습니다. –

+1

이것은 CSLA와 매우 흡사합니다. .NET을 사용하는 경우 체크 아웃하는 것이 좋습니다. http://www.lhotka.net –

1

편집중인 개체가있는 경우 isDirty()에 대한 부울 플래그 이외의 것이 필요할 수 있습니다. 이 문제는 참조 카운팅, 즉 실행 취소시 편집 및 감소시에 더티 카운트를 증가시키는 것과 유사하지 않다. 당신이 원상태로 돌아 가기를 원한다면 나는 꽤 털이 많은 논리로 끝날 것이라고 생각합니다. 나는 당신의 도메인 객체에서 그것을 지킬 것입니다.

1

예. 정상적으로 작동합니다. 실행 취소보다는 IsDirty 메서드를 사용하여 무언가가 레코드를 변경 한 다음 "변경된 레코드 변경"을 트리거한다는 것을 나타냅니다. 나는 모든 테이블 필드가 실제로 객체의 속성 인 자체 프레임 워크를 개발했습니다. 필드가 객체에 쓰여질 때마다 "isDirty"플래그가 설정됩니다. 객체의 SaveObject 메소드 (실제로는 도우미 클래스이지만 객체에 쉽게있을 수 있지만 XML, 데이터베이스 등 여러 가지 방법으로 객체를 저장할 수있는 기능을 원했습니다.)에서 IsDirty 및 false라면 저장을 건너 뜁니다. 이것은 객체를 변경할 가능성이있을 때마다 논리를 단순화하고, SaveObject를 호출하여 프레임 워크가 처리하도록합니다. 당신은 .NET 프레임 워크를 사용하는 경우

2

, 당신은 록 포드 Lhotka에 의해 CSLA .NET 프레임 워크에 대해 살펴 걸릴 할 수 있습니다 : 기능을 실행 취소 (IsDirty 사용)을 http://www.lhotka.net/cslanet/Default.aspx

CSLA 개체의 상태 관리를 포함하는 성숙 프레임 워크를, 데이터 바인딩과 훨씬 더 많은 기능을 제공합니다. 또한 무료이며 오픈 소스입니다.

1

도메인에 따라 차이점을 테스트하기 위해 평등성을 사용할 수 있습니다. 원래 개체를 유지하고 편집을 위해 개체의 복사본을 만듭니다. 편집이 수행 될 때마다 UI를 적절히 수정하십시오.

이 제안의 장점은

1

당신이 지원하는 경우 작업이보다 큰 단위의 수준에서 취소가 도메인 개체에 대한 GUI 특정 기능합니다 (IsDirty 사용() 플래그)를 부착하지 않는다는 것입니다,하지만 YMMV '마지막 저장 이후 모든 것을 취소하십시오.'그런 다음 실행 취소 스택을 제안합니다. 무언가가 편집되면 스택에 추가됩니다 (또는 작업 실행자 또는 델리게이트 실행 취소). 실행 취소하면 스택을 팝하고 팝업 된 작업을 실행 취소하기 만하면됩니다. 실행 취소 스택에 업데이트 할 추가 저장소 및 논리가 아닌 항목이 포함되어 있으면 isDirty() 플래그가 체크됩니다.

+0

제안 해 주셔서 감사합니다. 실행 취소 스택이 어디에 살고 있는지 궁금하네요. UndoManager 또는 스택에있는 별도의 객체입니까? 스택이 편집중인 도메인 객체에 연결되어 있습니까? –

2

INotifyPropertyChanged 및 IEditableObject와 같은 변경 내용 추적 및 실행 취소를 지원하는 몇 가지 인터페이스가 있습니다. 이 인터페이스들 모두는 객체가 데이터 바인딩으로 멋지게 플레이 할 수있게합니다.

public class Person : INotifyPropertyChanged, IEditableObject 
{ 
    private bool isDirty; 

    public bool IsDirty 
    { 
     get { return isDirty; } 
    } 

    private string firstname = string.Empty; 

    public string Firstname 
    { 
     get { return firstname; } 
     set 
     { 
      if (firstname == value) return; 
      firstname = value; 
      NotifyPropertyChanged("Firstname"); 
     } 
    } 

    private string lastname = string.Empty; 

    public string Lastname 
    { 
     get { return lastname; } 
     set 
     { 
      if (lastname == value) return; 
      lastname = value; 
      NotifyPropertyChanged("Lastname"); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    public void NotifyPropertyChanged(string propertyName) 
    { 
     isDirty = true; 

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

    private bool inTrans; 
    private Person copy; 

    public void BeginEdit() 
    { 
     if (!inTrans) 
     { 
      if (copy == null) 
       copy = new Person(); 

      copy.isDirty = isDirty; 
      copy.Firstname = Firstname; 
      copy.Lastname = Lastname; 


      inTrans = true; 
      isDirty = false; 
     } 
    } 

    public void CancelEdit() 
    { 
     if (inTrans) 
     { 
      isDirty = copy.isDirty; 
      Firstname = copy.Firstname; 
      Lastname = copy.Lastname; 

      inTrans = false; 
     } 
    } 

    public void EndEdit() 
    { 
     if (inTrans) 
     { 
      copy = null; 
      inTrans = false; 
     } 
    } 
}