2012-02-27 5 views
3

SimpleまたはPasswordモードでテキストを表示するためのカスタムコンポーネントを作成しました。このコントロールを開発する予定はです。SilverlightはカスタムTextMode(パスワードやテキストなど) 。ViewModelのCustomTextbox Textの実際の値と検証方法

これは、組織は、データベース内の特定のフィールドへのアクセス制限を指定することが可能になり、アクセス権に加えて、私の要件 です。これらのフィールドへのアクセス制限は、UpdateとRedactedになります。つまり、特定のフィールドがUpdateに対して真である場合、ユーザーはフィールドを更新するだけでなく表示することができます。フィールドがRedactedに該当する場合、ユーザーは(*アスタリスク - * * * *)のみで、編集された値を見ることができます。フィールドをUpdate-ableおよびRedactedに設定することができます。つまり、ユーザーは編集されたビューを表示しますが、フィールドを新しい値で更新することができます。このような要件は、連絡先に対して機密情報を保持する場合や、連絡先との差別化に使用できる情報を保持する場合に主に使用されます。

私はこの要件のカスタムコントロールを作成しており、完全に機能しています。私は動的にTextModeを設定することができますが、私はViewModelで元の値を取得できませんでした。 (私はViewで元の値を得ることができますが、ViewModelではできません)

私はViewで元の値にアクセスしています。

string s = UserName.Text; 

が、それは**のように私を与えているのViewModelにこの値を得ていません。

以下は、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 
    } 
} 

**私は2日後に解決策を探しています。

あなたはすべてのソリューションを持っている場合は、あなたの意見や提案が高く評価されるだろう、私を助けてください。**

おかげ

Imdadhusen

+0

ヒュム!非常に興味深い質問。あなたはここから答えを得ることを願っています..運が最高です。 –

+0

ありがとうございましたManoj、可能であれば手伝ってください! – imdadhusen

答えて

0

以下のコードを使用して解決しました。

私はLoginView.xamlにモード=双方向をしないのです:

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

おかげで、 Imdadhusen

0

が、周りにあなた自身のUserControlを構築することが容易ではないでしょう通常のTextBoxPasswordBoxを使用して、依存関係のプロパティTextModeが変更されたときの表示を切り替えるだけですか? ValueUserControlのVMを1つ持ち、のTextPropertyPasswordの両方のプロパティをTwoWayモードでバインドすることができます(PasswordBox)。