更新时间:2023-10-11 10:17:10
这是我的解决方案.由于我意识到用户控件的DataContext自动是父视图的ViewModel,所以我完全转储了Password依赖属性的绑定.我在控件中引入了一个新参数,该参数必须设置为父视图模型的密码属性.然后我使用这个字符串在控件的加载事件中手动绑定文本框和密码框.这是我的代码:
Here's my solution at last. Since I realized that the DataContext of the user control automatically is the ViewModel of the parent view, I dumped the binding of the Password dependency property completely. I introduced a new parameter in the control which has to be set to the password property of the parent view model. I then use this string to do a manual binding of the textbox and the password box in the loaded event of the control. Here's my code:
public partial class EAPPasswordBox : UserControl, INotifyPropertyChanged
{
public bool ShowText
{
get { return (bool)GetValue(ShowTextProperty); }
set {
SetValue(ShowTextProperty, value);
if (value == true)
{
this.pwdBox.Visibility = System.Windows.Visibility.Collapsed;
this.txtBox.Visibility = System.Windows.Visibility.Visible;
}
else
{
this.pwdBox.Visibility = System.Windows.Visibility.Visible;
this.txtBox.Visibility = System.Windows.Visibility.Collapsed;
}
}
}
public string PasswordPropertyName { get; set; }
private Visibility _PwdBoxVisibility;
public Visibility PwdBoxVisibility
{
get { return _PwdBoxVisibility; }
set
{
_PwdBoxVisibility = value; NotifyPropertyChanged("PwdBoxVisibility");
}
}
private Visibility _TxtBoxVisibility;
public Visibility TxtBoxVisibility
{
get { return _TxtBoxVisibility; }
set
{
_TxtBoxVisibility = value; NotifyPropertyChanged("TxtBoxVisibility");
}
}
public static readonly DependencyProperty ShowTextProperty =
DependencyProperty.Register("ShowText", typeof(bool), typeof(EAPPasswordBox), new PropertyMetadata(OnShowTextPropertyChanged));
public EAPPasswordBox()
{
InitializeComponent();
this.ShowText = false;
}
private static void OnShowTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
EAPPasswordBox passwordBox = d as EAPPasswordBox;
if (passwordBox != null)
{
passwordBox.ShowText=(bool)e.NewValue;
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
private void _root_Loaded(object sender, RoutedEventArgs e)
{
this.pwdBox.SetBinding(PasswordBox.PasswordProperty, new System.Windows.Data.Binding() { Source = this.DataContext, Path = new PropertyPath(PasswordPropertyName), Mode = BindingMode.TwoWay, ValidatesOnDataErrors = true });
this.txtBox.SetBinding(TextBox.TextProperty, new System.Windows.Data.Binding() { Source = this.DataContext, Path = new PropertyPath(PasswordPropertyName), Mode = BindingMode.TwoWay, ValidatesOnDataErrors = true });
}
}
这是控件的 XAML.
Here's the XAML of the control.
<UserControl x:Class="GAB.EAP2011.Controls.EAPPasswordBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400" x:Name="_root" Loaded="_root_Loaded">
<Grid x:Name="LayoutRoot" Background="White">
<StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Top">
<PasswordBox x:Name="pwdBox" />
<TextBox x:Name="txtBox" />
</StackPanel>
</Grid>
使用方法如下:
<local:EAPPasswordBox x:Name="pwdBox"
Grid.Column="1" Grid.Row="0" Grid.ColumnSpan="2" PasswordPropertyName="password" ShowText="{Binding showPassword,Mode=TwoWay}"></local:EAPPasswordBox>
现在你有了一个不错的密码可见性切换器控件:)评论赞赏!
Now you got a nice password visibility switcher control :) Comments appreciated!