WPF 附加属性的应用
有些控件的属性不是依赖属性无法进行数据绑定,可定义一个附加属性做为中间值来传递;例如PasswordBox控件的Password属性:
添加一个类:
class PasswordHelper
{
public static readonly DependencyProperty PasswordProperty =
DependencyProperty.RegisterAttached("Password", typeof(string), typeof(PasswordHelper), new FrameworkPropertyMetadata("", new PropertyChangedCallback(OnPropertyChanged)));
public static string GetPassword(DependencyObject d)
{
return d.GetValue(PasswordProperty).ToString();
}
public static void SetPassword(DependencyObject d,string value)
{
d.SetValue(PasswordProperty, value);
}
public static readonly DependencyProperty AttachProperty =
DependencyProperty.RegisterAttached("Attach", typeof(bool), typeof(PasswordHelper), new FrameworkPropertyMetadata(default(bool), new PropertyChangedCallback(OnAttachChanged)));
public static bool GetAttach(DependencyObject d)
{
return (bool)d.GetValue(PasswordProperty);
}
public static void SetAttach(DependencyObject d, bool value)
{
d.SetValue(PasswordProperty, value);
}
static bool _isUpdating = false;
private static void OnPropertyChanged(DependencyObject d,DependencyPropertyChangedEventArgs e)
{
PasswordBox password = d as PasswordBox;
password.PasswordChanged -= Password_PasswordChanged;
if (!_isUpdating)
password.Password = e.NewValue?.ToString();
password.PasswordChanged += Password_PasswordChanged;
}
private static void OnAttachChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
PasswordBox password = d as PasswordBox;
password.PasswordChanged += Password_PasswordChanged;
}
private static void Password_PasswordChanged(object sender, RoutedEventArgs e)
{
PasswordBox passwordBox = sender as PasswordBox;
_isUpdating = true;
SetPassword(passwordBox, passwordBox.Password);
_isUpdating = false;
}
}
使用方法:
<PasswordBox Grid.Row="1" Password="" Height="40" Style="{DynamicResource PasswordBoxStyle}" FontSize="16" Foreground="#555"
common:PasswordHelper.Attach="True"
common:PasswordHelper.Password="{Binding LoginModel.Password,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
<PasswordBox.InputBindings>
<KeyBinding Key="Enter" Command="{Binding LoginCommand}" CommandParameter="{Binding ElementName=loginwindow}"/>
</PasswordBox.InputBindings>
</PasswordBox>