我正在制作一个聊天程序。
我使用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}"
但我输入了PasswordBox
asdftest1234 。
我不知道为什么PasswordBox.Password
财产无法访问。
任何一个想法?
感谢。
答案 0 :(得分:1)
出于安全原因,无法直接绑定到PasswordProperty。
看看here!
答案 1 :(得分: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}"/>