2012-01-20 3 views
2

저는 조쉬 스미스가 자신의 sample application을 만든 방식에 항상 감탄했습니다. 그리고 자신의 응용 프로그램의 ViewModels에서 IDataErrorInfo 속성을 구현하고 사용자 정의 DataTemplate을 통해 사용자 앞에 오류를 렌더링하는 방식을 에뮬레이트하려고했습니다. 여기 은 그 오류를 표시하는 데 사용하는 데이터 템플릿입니다 다음과 같이WPF에서 오류 처리 암호 상자

<DataTemplate DataType="{x:Type ValidationError}"> 
    <TextBlock FontSize="10" 
      FontStyle="Italic" 
      Foreground="Red" 
      HorizontalAlignment="Right" 
      Margin="0,1" 
      Text="{Binding Path=ErrorContent}"/> 
</DataTemplate> 

소비지고,이 데이터 템플릿의 작업 예제는 다음과 같습니다

<TextBox x:Name="txtUsername" 
     Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2" 
     Width="300" 
     Margin="2" 
     Text="{Binding Path=Username, 
      ValidatesOnDataErrors=True, 
      UpdateSourceTrigger=PropertyChanged}" 
     Validation.ErrorTemplate="{x:Null}"/> 

<ContentPresenter Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2" 
        Content="{Binding ElementName=txtUsername, 
         Path=(Validation.Errors).CurrentItem}"/> 

텍스트 상자의 기본 ErrorTemplate (빨간색 그 주위에 나타나는 경계)는 텍스트 상자 바로 아래에 배치 된 컨텐트 프리젠터가 확실하게 우수하고보다 우아한 템플릿 인 사용자에게 — 오류를 전달하는 새로운 오류 템플리트로 대체됩니다.

위의 코드를 읽은 경우 로그인 양식을 만들려고하는 것 같습니다.

불행히도 로그인 양식은 비밀번호 (그리고이어서 PasswordBox)를 요구합니다. PasswordBox는 "Password"를 종속성 속성으로 제공하지 않습니다. 나는 가능한 한 코드 배제를 피하고자하는 MVVM 가이드 라인을 깨고 싶지 않았기 때문에 PasswordBoxAssistant 클래스에 대한 유혹은 here을 언급했다. 그렇지 않으면 한 가지를 제외하고는 멋진 해결책입니다. Josh의 데이터 템플릿으로 비밀번호 상자의 유효성을 검사하지 않습니다. 비어 있지 않은 ViewModel의 암호 속성을 확인했습니다. 사용자가 비밀번호를 입력하지 않으면 내 "로그인"버튼이 활성화되지 않으므로 속성의 유효성이 검사됩니다. 그러나이 속성 유효성 검사의 일부로 설정된 "암호 입력"메시지는 PasswordBox 아래에있는 콘텐츠 발표자에 의해 렌더링되지 않습니다.

xmlns:ff="clr-namespace:MyProject.UserViews" 

나는이 문제가 일어나고 확신 암호 속성을 확장 가지고 있기 때문에 : 위의 코드에서 FF로 네임 스페이스 참조를 의미 말을

<Label Content="Password:" Grid.Column="0" Grid.Row="2" Margin="2" /> 

<PasswordBox x:Name="PasswordBox" 
      Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2" 
      Margin="2" 
      Validation.ErrorTemplate="{x:Null}" 
      ff:PasswordBoxAssistant.BindPassword="true" 
      ff:PasswordBoxAssistant.BoundPassword="{Binding Path=Password, 
       Mode=TwoWay, 
       UpdateSourceTrigger=PropertyChanged}"/> 

<ContentPresenter Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="2" 
        Content="{Binding ElementName=PasswordBox, 
        Path=(Validation.Errors).CurrentItem}"/> 

없이 다음은 코드를 간다 도우미 클래스에 의해. 이 방법을 사용하지 않으면 IDataErrorInfo 구현에서 Password 속성을 제거해야하며 로그인 버튼을 클릭하면 메시지 상자가 표시된 사용자가이를 확인해야합니다. 그러나 일관성을 손상시키지 않고. 나는 Dependency Properties에 대해 많이 알지 못한다. 어떤 해결 방법이있을 수 있습니까? 도우미 클래스를 어떤 식 으로든 변경하면 적색 오류 메시지가 다시 나타납니다.

답변

4

암호 바인딩에 ValidatesOnDataErrors=True이 표시되지 않으므로 문제가 될 수 있습니다. 기본적으로이 값은 False으로 설정됩니다. 즉, 바인딩이 UI에 유효성 검사 오류를 알리지 않음을 의미합니다. 말했다


, 난 당신이 정말 일반 텍스트로 암호를 저장하지 않아야하기 때문에 Password 의도적으로 DependencyProperty하지라고 생각합니다.

보통 내 LoginCommandCommandParameterPasswordBox.Password (또는 전체 PasswordBox가), 다음 데이터를 받아 그것으로 원하는 건 뭐든지 할 수 있습니다 통과 끝낸다. 대개 이것은 해싱을 의미하거나 저장된 암호의 해시와 비교하여 같은지 확인합니다. 로그인이 실패하면 로그인 UI에 바인딩 된 내 ViewModel의 속성에 연결된 오류 메시지를 작성합니다.

<Button Command="{Binding LoginCommand}" 
     CommandParameter="{Binding ElementName=MyPasswordBox, Path=Password}" /> 
+0

답장을 보내 주셔서 감사합니다. 이 디자인을 시작하기 전에이 옵션을 사용했습니다. 필자의 경우, 로그인 모듈은 전통적인 접근 방식을 보존하기위한 공식적인 디자인에 가깝습니다. 내 문제는 내가 ViewModel에 암호를 전달하는 또 다른 방법을 장치 할 수있는 디자인이 아니라는 것이다. 내 문제는 어떻게 PasswordBoxAssistant가 유효성을 검사하지 못하도록 차단하고 있는지입니다. – James

+0

@James 패스워드 바인딩에'ValidatesOnDataErrors = "True"를 설정 했습니까? – Rachel

+0

"그렇다면 암호 바인딩에 ValidatesOnDataErrors = True가 표시되지 않으므로 문제가 될 수 있습니다." @Rachel 거기에 캐치가있었습니다. 그 점을 지적 해 주셔서 감사합니다. 나는 너에게 숙제를 던지면서 당혹 스럽다. – James

0

이것이 문제가 될지 확실하지 않지만 PasswordBox의 기본 ErrorTemplate을 끄는 것은 아닙니다. (즉, 어떤 Validation.ErrorTemplate="{x:Null})

편집 : 오류가 실제로 존재 (또는 단지에 ItemsControl에 바인딩) 것을 보장하기 위해 PasswordBoxValidation.Errors의 내용을 확인 Wpf Inspector 같은 것을 사용할 수 있습니까?

+0

마킹 해 주셔서 감사하지만 문제가되지는 않습니다. 기본 오류 템플리트를 끄지 않으면 기본 오류 템플리트가 표시 될 수 있습니다. 그러나 아무것도 나타나지 않습니다. – James