zoukankan      html  css  js  c++  java
  • WPF -- PasswordBox数据绑定方法

    本文介绍下PasswordBox进行数据绑定的方法,本文参考链接

    本文完整示例程序见GitHub

    问题描述

    PasswordBox的Password属性不是依赖属性,因此无法进行数据绑定。

    解决办法

    该问题的解决办法有多种,本文介绍如何通过添加附加属性解决该问题。

    附加属性是说一个属性本不属于某个对象,但由于某种需求附加到该对象上,通过附加属性可以实现将属性与宿主解耦的目的。附加属性本质上就是依赖属性,只是它们在属性包装器和注册时有区别。注册附加属性使用RegisterAttached方法,注册依赖属性使用Register方法,这两个方法的参数差别并不大。

    首先添加一个PasswordBoxBindingHelper类,该类包含一个附加属性(snippet:propa+两次tab),通过设置该属性的PropertyChangedCallback将改变通知到PasswordBox.Password,并通过添加对PasswordBox.PasswordChanged事件的响应来响应PasswordBox.Password的改变。有了该附加属性,即可进行数据绑定。

    public static string GetPasswordContent(DependencyObject obj) => (string)obj.GetValue(PasswordContentProperty);
    
    public static void SetPasswordContent(DependencyObject obj, string value) => obj.SetValue(PasswordContentProperty, value);
    
    public static readonly DependencyProperty PasswordContentProperty =
        DependencyProperty.RegisterAttached("PasswordContent", typeof(string), typeof(PasswordBoxBindingHelper),
        new PropertyMetadata(string.Empty, OnPasswordContentPropertyChanged));
    
    private static void OnPasswordContentPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var box = d as PasswordBox;
        box.PasswordChanged -= OnPasswordChanged;
        var password = (string)e.NewValue;
        if (box != null && box.Password != password)
            box.Password = password;
        box.PasswordChanged += OnPasswordChanged;
    }
    
    private static void OnPasswordChanged(object sender, RoutedEventArgs e)
    {
        var box = sender as PasswordBox;
        SetPasswordContent(box, box.Password);
    }
    

    然后在View中使用该附加属性进行数据绑定,本文示例中主窗口包含一个PasswordBox控件及一个Button按钮:

    // xaml 绑定附加属性
    <Window ...
            xmlns:local="clr-namespace:PasswordBoxBinding"
            Title="PasswordBoxBinding" Height="300" Width="450" WindowStartupLocation="CenterScreen">
    
        <Grid>
            <StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
                <PasswordBox MinWidth="200" Height="30" BorderBrush="LightGray" BorderThickness="2"
                             local:PasswordBoxBindingHelper.PasswordContent="{Binding Password,Mode=TwoWay}"/>
                <Rectangle Width="20"/>
                <Button Width="80" Height="30" Content="查看密码" Command="{Binding ClickedCommand}"/>
            </StackPanel>
        </Grid>
    </Window>
    
    //xaml.cs 设置绑定源
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = new MainWindowViewModel();
    }
    

    最后创建ViewModel进行逻辑处理:

    // ViewModel
    public class MainWindowViewModel : INotifyPropertyChanged
    {
        public string Password
        {
            get => _password;
            set
            {
                _password = value;
                OnPropertyChanged();
            }
        }
    
        public DelegateCommand ClickedCommand => _clickedCommand ?? (_clickedCommand = new DelegateCommand { ExecuteAction = OnClicked });
    
        // 使用CallerMemberName特性简化代码,并可以避免手动输入错误
        public void OnPropertyChanged([CallerMemberName] string name = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    
        private void OnClicked(object o) => MessageBox.Show($"password: {Password}");
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        private DelegateCommand _clickedCommand;
        private string _password;
    }
    
    // 实现ICommand
    public class DelegateCommand : ICommand
    {
        public bool CanExecute(object parameter) => CanExecuteAction?.Invoke(parameter) ?? true;
    
        public void Execute(object parameter) => ExecuteAction?.Invoke(parameter);
    
        public event EventHandler CanExecuteChanged;
    
        public Action<object> ExecuteAction { get; set; }
        public Func<object, bool> CanExecuteAction { get; set; }
    }
    
    转载请注明出处,欢迎交流。
  • 相关阅读:
    iap 详细
    血的教训,下次开工程 一点要写好判断空字符串方法
    iOS中的ScrollView
    自定义弹框加载方式
    CAGradientLayer简介(处理视图渐变色)
    iOS 制作view渐变的效果CAGradientLayer
    将vs2012的项目转化成VS2010
    关于Excel导入的HDR=YES; IMEX=1详解
    C#读取Excel表中的数据时,为何有些行的字段内容读取不到
    OLEDB读取EXCEL表格时,某些字段为空,怎么办?
  • 原文地址:https://www.cnblogs.com/louzixl/p/14919985.html
Copyright © 2011-2022 走看看