2014-09-10 89 views
1

我在做一個聊天程序。WPF密碼框密碼是「{DependencyProperty.UnsetValue}」

我用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}"

但我inputed到PasswordBoxasdftest1234

我不知道爲什麼PasswordBox.Password屬性不可訪問。

任何一個想法?

謝謝。

回答

1

出於安全原因,不可能直接綁定到PasswordProperty。

看看here!

+0

感謝。後來我回到家,我會試試這個! – Lee 2014-09-10 08:25:26

0

使用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}"/>