2012-02-27 87 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的属性。

相关问题