【问题标题】:WPF PasswordBox Password is "{DependencyProperty.UnsetValue}"WPF PasswordBox 密码为“{DependencyProperty.UnsetValue}”
【发布时间】:2014-09-10 08:08:27
【问题描述】:

我正在制作一个聊天程序。

我使用 XAML 设计了聊天室列表。

                                        <GridViewColumn x:Name="gridViewColumn_IsNeedPassword">
                                            <GridViewColumn.CellTemplate>
                                                <DataTemplate>
                                                    <PasswordBox x:Name="passwordBox_PW" MinWidth="100" IsEnabled="{Binding Path=IsNeedPassword}"/>
                                                </DataTemplate>
                                            </GridViewColumn.CellTemplate>
                                        </GridViewColumn>
                                        <GridViewColumn x:Name="gridViewColumn_EntryButton">
                                            <GridViewColumn.CellTemplate>
                                                <DataTemplate>
                                                    <Button Background="Aqua" Click="button_Entry_Click">
                                                        <StackPanel Orientation="Horizontal">
                                                            <Image Height="Auto" Width="Auto" Source="Resources/login.png"/>
                                                            <TextBlock Text="{Binding Converter={StaticResource EntryButtonConverter}}" VerticalAlignment="Center"/>
                                                        </StackPanel>
                                                        <Button.Tag>
                                                            <MultiBinding Converter="{StaticResource EntryButtonTagConverter}">
                                                                <Binding Path="ID"/>
                                                                <Binding Path="IsNeedPassword"/>
                                                                <Binding ElementName="passwordBox_PW" Path="Password"/>
                                                            </MultiBinding>
                                                        </Button.Tag>
                                                    </Button>
                                                </DataTemplate>
                                            </GridViewColumn.CellTemplate>
                                        </GridViewColumn>
                                        <GridViewColumn x:Name="gridViewColumn_DeleteButton">
                                            <GridViewColumn.CellTemplate>
                                                <DataTemplate>
                                                    <Button Background="Orange" Click="button_Delete_Click" IsEnabled="{Binding Path=Master, Converter={StaticResource DeleteButtonVisibilityConverter}}">
                                                        <StackPanel Orientation="Horizontal">
                                                            <Image Height="Auto" Width="Auto" Source="Resources/login.png"/>
                                                            <TextBlock Text="{Binding Converter={StaticResource DeleteButtonConverter}}" VerticalAlignment="Center"/>
                                                        </StackPanel>
                                                        <Button.Tag>
                                                            <Binding Path="ID"/>
                                                        </Button.Tag>
                                                    </Button>
                                                </DataTemplate>
                                            </GridViewColumn.CellTemplate>
                                        </GridViewColumn>
                                    </GridView.Columns>

类似的东西。

现在,在gridViewColumn_EntryButton 我需要一些信息,例如RoomID + IsNeedPassword + PasswordText

所以我使用了MultiBinding。

EntryButtonTagConverter.Convert 就是这样。

public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        string[] result = Array.ConvertAll<object, string>(values, obj =>
        {
            return (obj == null) ? string.Empty : obj.ToString();
        });
        // RoomID + IsNeedPassword + PasswordText
        return result[0] + '\n' + result[1] + '\n' + result[2];
    }

当我调试时,result[2]、PasswordText 是"{DependencyProperty.UnsetValue}"

但是我输入了PasswordBoxasdftest1234。

我不知道为什么PasswordBox.Password 属性不可访问。

大家有什么想法吗?

谢谢。

【问题讨论】:

    标签: c# wpf binding passwordbox


    【解决方案1】:

    出于安全原因,无法直接绑定到 PasswordProperty。

    看看here!

    【讨论】:

    • 谢谢。后来我回到家我会试试这个!
    【解决方案2】:

    使用 PasswordBoxAssistant 可以绑定密码。

    public static class PasswordBoxAssistant
    {
        public static readonly DependencyProperty BoundPasswordProperty =
            DependencyProperty.RegisterAttached("BoundPassword", typeof(string)
            , typeof(PasswordBoxAssistant), new FrameworkPropertyMetadata(string.Empty, OnBoundPasswordChanged));
    
        public static readonly DependencyProperty BindPasswordProperty = DependencyProperty.RegisterAttached(
            "BindPassword", typeof(bool), typeof(PasswordBoxAssistant), new PropertyMetadata(false, OnBindPasswordChanged));
    
        private static readonly DependencyProperty UpdatingPasswordProperty =
            DependencyProperty.RegisterAttached("UpdatingPassword", typeof(bool), typeof(PasswordBoxAssistant));
    
        private static void OnBoundPasswordChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            PasswordBox box = d as PasswordBox;
    
            // only handle this event when the property is attached to a PasswordBox  
            // and when the BindPassword attached property has been set to true  
            var ignoreBindProperty = false;
            if (box != null && box.Parent != null)
            {// TODO: Bind property change not set in case of hosting password box under Telerik datafield. That why I am ignoring the bind propery here - Morshed
                ignoreBindProperty = (box.Parent is Telerik.Windows.Controls.DataFormDataField);
            }
    
            if (d == null || !(GetBindPassword(d) || ignoreBindProperty))
            {
                return;
            }
    
            // avoid recursive updating by ignoring the box's changed event  
            box.PasswordChanged -= HandlePasswordChanged;
    
            string newPassword = (string)e.NewValue;
    
            if (!GetUpdatingPassword(box))
            {
                box.Password = newPassword;
            }
    
            box.PasswordChanged += HandlePasswordChanged;
        }
    
        private static void OnBindPasswordChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e)
        {
            // when the BindPassword attached property is set on a PasswordBox,  
            // start listening to its PasswordChanged event  
    
            PasswordBox box = dp as PasswordBox;
    
            if (box == null)
            {
                return;
            }
    
            bool wasBound = (bool)(e.OldValue);
            bool needToBind = (bool)(e.NewValue);
    
            if (wasBound)
            {
                box.PasswordChanged -= HandlePasswordChanged;
            }
    
            if (needToBind)
            {
                box.PasswordChanged += HandlePasswordChanged;
            }
        }
    
        private static void HandlePasswordChanged(object sender, RoutedEventArgs e)
        {
            PasswordBox box = sender as PasswordBox;
    
            // set a flag to indicate that we're updating the password  
            SetUpdatingPassword(box, true);
            // push the new password into the BoundPassword property  
            SetBoundPassword(box, box.Password);
            SetUpdatingPassword(box, false);
        }
    
        public static void SetBindPassword(DependencyObject dp, bool value)
        {
            dp.SetValue(BindPasswordProperty, value);
        }
    
        public static bool GetBindPassword(DependencyObject dp)
        {
            return (bool)dp.GetValue(BindPasswordProperty);
        }
    
        public static string GetBoundPassword(DependencyObject dp)
        {
            return (string)dp.GetValue(BoundPasswordProperty);
        }
    
        public static void SetBoundPassword(DependencyObject dp, string value)
        {
            dp.SetValue(BoundPasswordProperty, value);
        }
    
        private static bool GetUpdatingPassword(DependencyObject dp)
        {
            return (bool)dp.GetValue(UpdatingPasswordProperty);
        }
    
        private static void SetUpdatingPassword(DependencyObject dp, bool value)
        {
            dp.SetValue(UpdatingPasswordProperty, value);
        }
    }
    

    并在 xaml 中更改

    <PasswordBox helpers:PasswordBoxAssistant.BindPassword="true"
                  helpers:PasswordBoxAssistant.BoundPassword="{Binding Path=Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=true}"/>
    

    【讨论】:

      猜你喜欢
      • 2014-09-19
      • 1970-01-01
      • 2014-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-01
      • 1970-01-01
      相关资源
      最近更新 更多