2011-02-06 2 views
9

저는 MVVM을 처음 사용하기 때문에 앞으로 다가올 프로젝트에서이 기술을 채택하고 채택하기로 결정했습니다.MVVM에서보기 모드와 편집 모드간에 전환 하시겠습니까?

이 관련 질문과 대답을 읽었지만 이것이 MVVM으로 어떻게 구현되는지 모르겠습니다.

내 프로젝트의 모든보기에 2 개의 모드, 편집 모드 및보기 모드가 있어야합니다.
기본적으로 사용자가 모든 필드에 대해 TextBoxes를 보지 못하도록하고 싶습니다. 대신 TextBlocks를 보거나 (TextBoxe '을 IsReadOnly 속성으로 설정하면 스타일 등을 통해 알 수 있습니다.)

사용자가 엔티티를 열면 일반적으로 TextBlocks, Labels (또는 읽기 전용 텍스트 상자) 등이되어야하며 "편집"(권한이있는 경우)을 클릭하면 편집 모드로 들어가야하고 모든 필드의 레이블은 TextBoxes (RichTextBoxes 등, ComboBoxes 또는 레이블이 아닌 다른 편집 가능한 필드)로 반전되어야합니다.

저는이 문제가있는 유일한 사람이 아니라고 확신합니다. 전문가로부터 가장 효율적인 방법은 무엇입니까? 순수 MVVM에서 이러한 모드 사이에, 그리고 그것의 두 가지 별도의보기를 선언하는 것이 일반적인지 여부입니다.

어떻게하면되는지 설명하는 좋은 기사를 참조하십시오. (아마도 Visual State? IDK로 수행됩니다.)

UPDATE
내가 알고 싶은 무엇 오히려 방법보다 내 질문 패턴에 대해, 그리고 내가 V 또는 VM 중 하나에서보기 모드에서 편집 모드 을 분리해야입니까? 답변에서이 세부 사항을 강조하십시오.

미리 감사드립니다.

답변

10

텍스트 상자의 IsReadOnly 속성을 사용하고 "편집 모드"속성이 바인딩 : 뷰 모델에서 다음

<TextBox .... IsReadOnly={Binding IsViewMode} ... /> 

:

public bool IsViewMode 
{ 
    get { return _IsViewMode; } 
    set 
    { 
     _IsViewMode= value; 
     // Call NotifyPropertyChanged when the source property is updated. 
     NotifyPropertyChanged("IsViewMode"); 
    } 
} 

IsViewMode 기본값을 true 및 전환 사용자가 "편집"을 클릭하면 false으로 변경됩니다. 바인딩은 즉시 모든 텍스트 상자를 편집 가능하게 만듭니다.

다른 컨트롤에 대해서도 동일한 작업을 수행 할 수 있습니다. 컨트롤을 회색으로 처리하더라도이 경우 바인딩해야 할 IsEnabled 속성이됩니다.

<TextBlock Grid.Row="1" Grid.Column="2" ... 
      Visiblity={Binding IsViewMode, Converter=DirectConverter} ... /> 
<ComboBox Grid.Row="1" Grid.Column="2" ... 
      Visiblity={Binding IsViewMode, Converter=InvertedConverter} ... /> 

직접적인을 :

는 컨버터의 한 쌍을 통해 IsViewMode 속성에 의해 제어 두 그리드에서 같은 위치를 공유 컨트롤과 자신의 가시성을 확보해야합니다 텍스트 블록과 컨트롤을 교환하려면 변환은 다음과 같습니다

return IsViewMode ? Visibility.Visible : Visibility.Collapsed; 

반전 변환은 다음과 같습니다

return IsViewMode ? Visibility.Collapsed : Visibility.Visible; 
+0

그리고 다른 분야는 어떻습니까? 일부 필드는 드롭 다운으로, 일부는 슬라이더로, 일부는 날짜 선택으로,보기 모드에서는 모두 간단한 TextBlocks/레이블을 사용하고 싶습니다. 그리고 그것은 저에게 아주 필수적인 부분입니다. – Shimmy

+0

@Shimmy - 죄송합니다. 그 이유는 모르겠습니다. ComboBox에 대해서도 동일한 작업을 수행 할 수 있지만 바인딩 할 필요가있는 IsEnabled 속성 일 수 있습니다. – ChrisF

+0

그래서 기본적으로 편집 /보기 모드에 대한 일반 뷰를 작성해야하며 모든 컨트롤이 IsReadOnly 또는 Visibility 컨트롤을 VM의 IsViewMode (컨트롤을 숨기려면 BooleanToVisibility 변환기 사용)에 설정하는 것과 비슷합니다. 맞지? ** 내 질문에 일부 내용을 추가했습니다. ** – Shimmy

2

Viewmodel : 나는 확실히 ViewMode 속성을 가진 하나의 viewmodel을 ChrisF의 답변에 설명 된대로 유지합니다. 별도의 ViewModel은 비효율적입니다.

보기 : 제가보기에, 당신에게는 여러 찬부 양론이있는 적어도 세 가지 옵션이 있습니다.

  1. ChrisF의 답변에서 제안한대로 모든 컨트롤을 읽기만하면됩니다. 장점 : 할 일이 가장 간단합니다. 단점 : 저의 겸손한 견해는 추한 UI입니다.

  2. seaparate 디스플레이를 만들고 별도의 컨테이너에서 컨트롤을 편집하십시오. ViewMode에 대한 컨테이너의 가시성을 바인딩합니다. 장점 :보다 즐거운 경험을 여기에서 얻을 수 있습니다. 트랜지션을 하나에서 다른 것으로 애니 메이팅 할 수도 있습니다. 단점 : 컨트롤의 수를 두 배로 만듭니다 (매우 큰 창에 대한 성능을 해칠 수 있음). 정확히 동일한 픽셀 위치에 두 콘테이너 안의 컨트롤을 배치하는 것은 유동적 인면에서 약간 사소한 일이 될 수 있습니다.

  3. xaml의 모든 편집 컨트롤에 대해 오른쪽 위에 디스플레이 컨트롤을 배치하십시오. ViewMode 속성에 대한 가시성을 바인딩하십시오. 장점 : 레이블 컨트롤의 중복이 거의 없으므로 약간 더 빠릅니다. 단점 : 애니메이션 작업 및 기타보기 수정이 어려워집니다.

편집 : 제공되는 설명의 관점에서, 나는 그것이 거의 대부분 어떻게 처리 아니라 무엇으로 이전 답을 교체하기로 결정했습니다.

+0

내 질문에 일부 내용을 추가했습니다. 나는 이렇게 선언하지 않을 것이다. ViewModel은 Visibility 열거 형이 있음을 알고 있다는 것을 싫어합니다 ... [ChrisF의 답변] (http://stackoverflow.com/questions/4917047/switching-between-view-mode-and-edit-mode-in)을 따를 것입니다. -mvvm/4917104 # 4917104) BooleanToVisibilit/BooleanFlagSwitch 변환기 등을 사용합니다.보기 모드와 편집 모드가 분리되어서는 안된다는 답변을 받았습니다. – Shimmy

+0

@Shimmy : 디스플레이 및 편집 모드는 동일한 뷰 클래스에 속해야하며 동일한 뷰 모델에 바인딩되어야하지만 컨트롤은보다 나은 UI 경험을 위해 분리되어야한다고 생각합니다. 같은 것을 반영하도록 대답을 변경했습니다. – anshul

+1

가시성과 같은 것이 있다는 것을 알고있는 뷰 모델에는 아무런 문제가 없습니다. –

3

저는이 방법에 대해 생각합니다.보기는 모양이 같고 ViewModel은 사용자와 상호 작용하는 방식입니다. 읽기 전용 인터페이스는 읽기/쓰기 인터페이스와 실질적으로 다른 동작을하기 때문에 두 개의 서로 다른 ViewModel이 있어야합니다.

이제 편집 기능을 디스플레이 기능의 확장으로 간주했기 때문에 디스플레이 ViewModel에서 상속 한 Edit ViewModel을 만들었습니다. 이 기능은 사용자가 많은 비즈니스 로직없이 필드를 직접 편집하는 간단한 CRUD 유형 응용 프로그램에 적합합니다.

반면에 모델링하는 비즈니스 프로세스 (또는 워크 플로)가 복잡하면 일반적으로 정보를 조작하는 방식이 보 기 방식과 매우 다릅니다. 따라서 CRUD가 아니라면 일반적으로 두 개의 ViewModel을 분리합니다.

+0

정확하게 CRUD에 대해 이야기하고 있습니다 .MVVM을 처음 사용하면서 배우기를 원합니다. CRUD 응용 프로그램을 MVVM 방식으로 구현하는 방법에 대한 훌륭한 기사를 참조 할 수 있습니까? 내 문제는 다른보기. – Shimmy

+0

정확하게, 나는 CRUD에 대해 말하고있다. 내가 MVVM에 익숙하지 않고 그것을 배우고 싶다. 당신이 CRUD 응용 프로그램을 MVVM 방식으로 구현하는 방법에 대한 좋은 기사를 참조 할 수 있는가? ** 나의 메인 문제는 다른보기 간의 전환이기도합니다.** – Shimmy

+1

@Shimmy - Josh Smith의 [Advanced MVVM] (http://joshsmithonwpf.wordpress.com/advanced-mvvm/)을 제안합니다. 짧지 만 유익하고 소스 코드를 얻을 수 있습니다. –

3

IsReadOnly 경로로 이동하려면 ChrisF의 대답은 문제가 없습니다. TextBlock-to-TextBox 경로를 만들고 싶다면 가장 효율적인 방법은 IsInEditMode 또는 IsInViewModel 속성 값을 기반으로 트리거를 통해 템플릿을 전환하는 Control을 만드는 것입니다.

2

첫째, IEditableObject을 구현 BeginEdit, EndEditCancelEdit 적절한 명령을 노출 내보기 모델의 추상 기본 클래스를 구현하는 것입니다. 이 세 가지 메소드의 실제 구현은 파생 클래스까지 있어야하지만 명령은 기본 클래스에있을 수 있습니다.

이 접근 방식에서 EndEdit은 뷰 모델의 현재 등록 정보 값으로 모델을 업데이트합니다.

데이터 트리거에 사용하기 위해 부울 IsEditing 속성을 기본 클래스에 구현하므로 모달 대화 상자를 열지 않고 모드간에 전환하려는 경우 스타일로 만 수행 할 수 있습니다. .

프런트 엔드의 시각적 디자인에 관한 한, 읽기 전용보기는 읽기 전용 컨트롤이있는 편집보기에 불과하다는 생각을 주로 프로그래머에게 호소하는 개념입니다. 일반적으로 말하자면, 단순히 사용자에게 객체를 제시한다면, 그 프리젠 테이션의 목적은 해당 객체의 정보를 유익하고 명확하며 직관적으로 표현하는 것입니다. 사용자가 개체를 편집하게하는 경우 해당 프레젠테이션의 목표는 개체의 편집 가능한 모든 속성을 가능한 쉽고 명확하게 수정하는 작업을 만드는 것입니다.

두 가지 매우 다른 목표 세트입니다. 예를 들어, 사람의 성별, 키 및 체중이 수집하는 응용 프로그램의 중요한 정보 일 수는 있지만 시스템이 대부분의 상황에서 해당 정보를 사용자에게 제공하는 것이 중요하지는 않습니다. 당신이 머리 속에 가지고있는 것이 편집 모드가 마치 디스플레이 모드와 같다면 그것은 매우 자연스러운 일입니다. 그러나 프로그래머, 프론트 및 센터가 아닌 사용자의 요구를 충족시키는 경우, 전혀 옳지 않을 수 있습니다.

관련 문제