2012-01-20 42 views
2

我一直很欣賞Josh Smith建立他的sample application的方式。 我也嘗試模仿他的應用程序的ViewModel實現IDataErrorInfo屬性的方式,並通過自定義DataTemplate在用戶之前呈現錯誤。 下面是他用來顯示錯誤數據模板:WPF PasswordBox中的錯誤處理

<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不提供「密碼」作爲依賴項屬性。我不想打破儘可能避免代碼背後的MVVM指導原則,所以很想去PasswordBoxAssistant提到here。 否則這是一個不錯的解決方案,保存一件事。它不讓我用Josh的數據模板驗證密碼框。 我驗證了我的ViewModel的密碼屬性不爲空。該屬性得到驗證,因爲我的「登錄」按鈕沒有啓用沒有用戶填寫密碼。但是我確實設置爲屬性驗證的一部分的「輸入密碼」消息並未由位於PasswordBox下方的Content Presenter呈現。這裏有雲代碼:

<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}"/> 

不用說,在上面的代碼中的FF代表的命名空間引用:

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

我相信,這個問題正在發生,因爲Password屬性已得到擴展由助手類。如果我放棄這種方法,我將不得不從IDataErrorInfo實施中刪除密碼屬性,並在登錄按鈕單擊將不得不驗證它,向用戶提供一個消息框。但不是沒有妥協的一致性。我不太瞭解依賴屬性;可以有任何解決方法嗎?將以某種方式改變助手類讓我有紅色的錯誤信息回來?

回答

4

我沒有在你的密碼綁定中看到ValidatesOnDataErrors=True,所以也許這就是你的問題。默認情況下,它被設置爲False,這意味着綁定不會向用戶界面提示任何驗證錯誤。


這麼說,我覺得Password是故意不DependencyProperty,因爲你真的不應該存儲密碼爲純文本。

通常我最終經過PasswordBox.Password(或整個PasswordBox)作爲CommandParameterLoginCommand,那麼它可以採取的數據,做任何它想要它。通常這意味着對它進行哈希處理,並將它與存儲的密碼哈希進行比較,以查看它是否相同。如果登錄失敗,我將相關的錯誤消息寫入ViewModel中的屬性,該屬性綁定到登錄UI。

<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。 (即沒有0​​)

編輯:您可以使用類似Wpf Inspector檢查的PasswordBoxValidation.Errors的內容,以確保該錯誤是實際存在(甚至只是一個ItemsControl綁定到它)?

+0

感謝標記,但這不能成爲問題。因爲不關閉默認錯誤模板會使默認錯誤模板出現。但沒有出現。 – James