2012-02-27 85 views
3

我創建了用於以簡單或密碼模式顯示文本的自定義組件,意圖開發此控件是Silverlight不支持自定義TextMode(如密碼或文本) 。如何在ViewModel中獲取CustomTextbox文本的實際值和驗證

這是我的要求 除了訪問權限,將有可能爲組織指定數據庫中的某些領域限制進入。對這些字段的訪問限制將是Update和Redacted,這意味着如果特定字段對Update更新,則用戶將能夠更新字段以及查看它,並且如果該字段對Redlease有效,則用戶將只能在字段中看到一個編輯值(可能是星號 - * * * * *)。可以將字段設置爲Update-able和Redacted,這意味着用戶將看到編輯的視圖,但仍然可以使用新值更新字段。這種要求主要用於保存針對聯繫人的敏感信息或可能用於歧視聯繫人的信息。

我已經爲此需求創建了自定義控件,並且它工作正常。我能夠動態設置TextMode,但我無法在ViewModel中獲取原始值。 (我能夠在視圖中獲得原始值,但不能在ViewModel中)

如果我使用以下方式訪問View中的原始值,那麼這是工作。

string s = UserName.Text; 

但視圖模型沒有得到這個值是給我像**

以下是PasswordTextBox控件的完整代碼。

namespace QSys.Library.Controls 
{ 
    public partial class PasswordTextBox : TextBox 
    { 
     #region Variables 
     private string text = string.Empty; 
     private string passwordChar = "*"; 
     private int selectionLength = 0; 
     #endregion 

     #region Properties 
     /// <summary> 
     /// The text associated with the control. 
     /// </summary> 
     public new string Text 
     { 
      get { return text; } 
      set 
      { 
       text = value; 
       DisplayMaskedCharacters(); 
      } 
     } 
     /// <summary> 
     /// Indicates the character to display for password input. 
     /// </summary> 
     public string PasswordChar 
     { 
      get { return passwordChar; } 
      set { passwordChar = value; } 
     } 
     /// <summary> 
     /// Indicates the input text mode to display for either text or password. 
     /// </summary> 
     public Mode TextMode 
     { 
      get { return (Mode)GetValue(TextModeProperty); } 
      set { SetValue(TextModeProperty, value); } 
     } 
     public static readonly DependencyProperty TextModeProperty = DependencyProperty.Register("TextMode", typeof(Mode), typeof(PasswordTextBox), new PropertyMetadata(default(Mode))); 
     #endregion 

     #region Constructors 
     public PasswordTextBox() 
     { 
      this.Loaded += new RoutedEventHandler(PasswordTextBox_Loaded); 
     } 
     #endregion 

     #region Event Handlers 
     void PasswordTextBox_Loaded(object sender, System.Windows.RoutedEventArgs e) 
     { 
      if (this.TextMode == Mode.Password) 
      { 
       text = base.Text; 
       this.TextChanged += new TextChangedEventHandler(PasswordTextBox_TextChanged); 
       this.KeyDown += new KeyEventHandler(PasswordTextBox_KeyDown); 
       this.SelectionChanged += new RoutedEventHandler(PasswordTextBox_SelectionChanged); 
       DisplayMaskedCharacters(); 
      } 
      this.Loaded -= PasswordTextBox_Loaded; 
     } 
     void PasswordTextBox_SelectionChanged(object sender, RoutedEventArgs e) 
     { 
      selectionLength = this.SelectionLength; 
     } 
     public void PasswordTextBox_TextChanged(object sender, TextChangedEventArgs e) 
     { 
      if (base.Text.Length >= text.Length) 
       text += base.Text.Substring(text.Length); 
      else 
      { 
       int cursorPosition = this.SelectionStart; 
       selectionLength = (selectionLength > 1) ? selectionLength : 1; 
       text = text.Remove(cursorPosition, selectionLength); 
      } 
      DisplayMaskedCharacters(); 
      selectionLength = 0; 
     } 
     public void PasswordTextBox_KeyDown(object sender, System.Windows.Input.KeyEventArgs e) 
     { 
      int cursorPosition = this.SelectionStart; 
      // Handle Delete and Backspace Keys Appropriately 
      if (e.Key == System.Windows.Input.Key.Back && cursorPosition > 0) 
      { 
       DeleteAt(cursorPosition); 
      } 
      else if (e.Key == System.Windows.Input.Key.Delete) 
      { 
       DeleteAt(cursorPosition); 
      } 
      else 
      { 
       if (selectionLength > 0) text = text.Remove(cursorPosition, selectionLength); 
       base.Text = text; 
       this.Select((cursorPosition > text.Length ? text.Length : cursorPosition), 0); 
       DisplayMaskedCharacters(); 
      } 
      selectionLength = 0; 
     } 
     #endregion 

     #region Private Methods 
     private void DisplayMaskedCharacters() 
     { 
      int cursorPosition = this.SelectionStart; 
      // This changes the Text property of the base TextBox class to display all Asterisks in the control 
      base.Text = new string(passwordChar.ToCharArray()[0], text.Length); 
      this.Select((cursorPosition > text.Length ? text.Length : cursorPosition), 0); 
     } 
     private void DeleteAt(int position) 
     { 
      if (text.Length > position) 
      { 
       text = text.Remove(position, 1); 
       base.Text = base.Text.Remove(position, 1); 
      } 
     } 
     #endregion 
    } 
} 

LoginView.xaml

<control:PasswordTextBox x:Name="UserName" TabIndex="1" Grid.Row="1" TextMode="Password" Text="{Binding Path=LoginModelValue.UserName, Mode=TwoWay,ValidatesOnNotifyDataErrors=True, ValidatesOnExceptions=True, ValidatesOnDataErrors=True, NotifyOnValidationError=True}" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Column="1" Width="200" Height="25" Validatevalue:UpdateSourceTriggerHelper.UpdateSourceTrigger="True"/> 

LoginViewModel.cs

public class LoginViewModel : INotifyPropertyChanged, IRegionMemberLifetime 
    { 
public LoginModel LoginModelValue 
     { 
      get { return _LoginModelValue; } 
      set 
      { 
       _LoginModelValue = value; 
       OnPropertyChanged("LoginModelValue"); 
      } 
     } 
} 

LoginModel.cs

namespace QSys.Model 
{ 
    public class LoginModel : INotifyPropertyChanged 
    { 
     #region Variables 
     private string _userName; 
     private string _password; 
     #endregion 

     #region Constructor 
     public LoginModel() 
     { 
     } 
     #endregion 

     #region Properties 
     [CustomValidation(typeof(PasswordTextBox), "IsValidUserName")] 
     [Required(ErrorMessage = "User Name is required")] 
     [Display(Name = "UserName")] 
     [StringLength(50)] 
     //[RegularExpression(@"^[a-zA-Z\\0-9\\.\\,\\'\s]+$", ErrorMessage = "Please enter right format.")] 
     public string UserName 
     { 
      get { return _userName; } 
      set 
      { 
       _userName = value; 
       OnPropertyChanged("UserName"); 
       ValidateProperty("UserName", value); 
      } 
     } 
     [Required(ErrorMessage = "Password is required")] 
     [Display(Name = "Password")] 
     [StringLength(10)] 
     public string Password 
     { 
      get { return _password; } 
      set 
      { 
       _password = value; 
       OnPropertyChanged("Password"); 
       ValidateProperty("Password", value); 
      } 
     } 
     #endregion 

     #region INotifyPropertyChanged 
     public event PropertyChangedEventHandler PropertyChanged = delegate { }; 
     private void OnPropertyChanged(string propertyName) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
     #endregion 

     #region Private Methods 
     public bool IsValidObject() 
     { 
      ICollection<ValidationResult> results = new Collection<ValidationResult>(); 
      return Validator.TryValidateObject(this, new ValidationContext(this, null, null), results, true) && results.Count == 0; 
     } 
     public void ValidateProperty(string propertyName, object value) 
     { 
      Validator.ValidateProperty(value, new ValidationContext(this, null, null) { MemberName = propertyName }); 
     } 
     #endregion 
    } 
} 

**我正在尋找解決方案,因爲兩天沒有任何運氣。

請幫助我,如果你有任何解決方案,您的意見或建議將高度讚賞。**

感謝

Imdadhusen

+0

姆!非常有趣的問題。希望你能從這裏得到答案..祝你好運。 – 2012-02-27 06:20:32

+0

感謝Manoj,如果可能的話,請幫助我! – imdadhusen 2012-02-27 06:21:28

回答

0

我已經解決了使用下面的代碼。

我失蹤模式=雙向在LoginView.xaml:

<control:RestrictedBox Type="Text" Value="{Binding Path=UserName,Mode=TwoWay}"> 

感謝, Imdadhusen

0

那豈不是更容易建立自己的UserControl各地經常TextBoxPasswordBox,只是當您的依賴項屬性TextMode更改時切換其可見性?然後,您可以爲UserControl擁有一臺虛擬機,並使用屬性Value,並以TwoWay模式綁定TextBoxTextPropertyPasswordBox的屬性。

相關問題