我提供了一个示例程序:当在PasswordBox中按Tab键进入并输入文本,然后按Tab键退出时,似乎会导致PasswordBox变为空白。但是在PasswordBox中双击、输入文本并按Tab键不会出现这种情况。为什么会发生这种情况?
编辑:我发现这也会发生在TextBox上,所以这不是PasswordBox特有的错误。
重现每种情况的步骤:
使密码消失
- 点击“新建”。 - 单击第一个名字字段。 - 输入一些内容。 - 按Tab键。 - 输入一些内容。 - 按Tab键。 - 按两次Tab键(否则Save事件会触发)。 - 输入一些内容。 - 注意到点而不是文本 - PasswordBox正常工作! - 按Tab键。 - 让你的朋友惊叹,因为PasswordBox变成空白了!
使密码不消失
- 点击“新建”。 - 单击第一个名字字段。 - 输入一些内容。 - 按Tab键。 - 输入一些内容。 - 在密码字段中双击。 - 输入一些内容。 - 注意到点而不是文本 - PasswordBox正常工作! - 按Tab键。 - 让你的朋友惊叹...等等,PasswordBox没有变空?WTF?
示例代码:
编辑:我发现这也会发生在TextBox上,所以这不是PasswordBox特有的错误。
重现每种情况的步骤:
使密码消失
- 点击“新建”。 - 单击第一个名字字段。 - 输入一些内容。 - 按Tab键。 - 输入一些内容。 - 按Tab键。 - 按两次Tab键(否则Save事件会触发)。 - 输入一些内容。 - 注意到点而不是文本 - PasswordBox正常工作! - 按Tab键。 - 让你的朋友惊叹,因为PasswordBox变成空白了!
使密码不消失
- 点击“新建”。 - 单击第一个名字字段。 - 输入一些内容。 - 按Tab键。 - 输入一些内容。 - 在密码字段中双击。 - 输入一些内容。 - 注意到点而不是文本 - PasswordBox正常工作! - 按Tab键。 - 让你的朋友惊叹...等等,PasswordBox没有变空?WTF?
示例代码:
using System;
using System.Collections.ObjectModel;
namespace WpfApplication1 {
public sealed class MyData {
private ObservableCollection<MyDataRow> dataList;
public ObservableCollection<MyDataRow> DataList { get { return dataList; } }
public MyData() { dataList = new ObservableCollection<MyDataRow>(); }
public void AddBlankRow() { DataList.Add(new MyDataRow(this)); }
}
public sealed class MyDataRow {
private readonly MyData myData;
public MyDataRow(MyData myData) { this.myData = myData; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Password { get; set; }
}
}
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace WpfApplication1 {
public partial class MainWindow : Window {
private MyData Data { get { return (MyData)DataContext; } }
public MainWindow() { InitializeComponent(); }
private void PasswordBox_PasswordChanged(object sender, RoutedEventArgs e) {
PasswordBox pb = (PasswordBox)sender;
if (pb != null) {
MyDataRow row = pb.DataContext as MyDataRow;
if (row != null) { row.Password = pb.Password; }
}
}
private void Window_Loaded(object sender, RoutedEventArgs e) { DataContext = new MyData(); }
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) { }
private void SaveExecute(object sender, ExecutedRoutedEventArgs e) { }
private void NewExecute(object sender, ExecutedRoutedEventArgs e) { Data.AddBlankRow(); }
private void CancelExecute(object sender, ExecutedRoutedEventArgs e) { Close(); }
}
}
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded" WindowStartupLocation="CenterScreen" Closing="Window_Closing">
<Window.CommandBindings>
<CommandBinding Command="Save" Executed="SaveExecute" />
<CommandBinding Command="New" Executed="NewExecute" />
<CommandBinding Command="Close" Executed="CancelExecute" />
</Window.CommandBindings>
<Grid Margin="0,10,0,0">
<DataGrid ItemsSource="{Binding DataList}" ColumnWidth="*" Margin="10,0,9,38" HorizontalAlignment="Stretch"
AutoGenerateColumns="False" GridLinesVisibility="Horizontal"
HeadersVisibility="Column" HorizontalGridLinesBrush="LightGray" CanUserReorderColumns="False" Background="White" >
<DataGrid.Columns>
<DataGridTextColumn Header="First Name" Binding="{Binding FirstName}"/>
<DataGridTextColumn Header="Last Name" Binding="{Binding LastName}"/>
<DataGridTemplateColumn Header="Password" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<PasswordBox PasswordChanged="PasswordBox_PasswordChanged" BorderThickness="0"
Height="23" HorizontalAlignment="Stretch"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
<Button
Content="_New" Command="New"
Width="75" Height="23" Margin="10,10,10,10"
HorizontalAlignment="Left" VerticalAlignment="Bottom"/>
<Button
Content="_Save" Command="Save"
IsDefault="True"
IsEnabled="True"
Width="75" Height="23" Margin="10,10,91,10"
HorizontalAlignment="Right" VerticalAlignment="Bottom" />
<Button
Content="Cancel" Command="Close"
IsEnabled="True"
Width="75" Height="23" Margin="10,10,10,10"
HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
</Grid>
</Window>
编辑
使用数据模板来设置CellTemplate和EditingCellTemplate,我的解决方法很简单-始终显示一些内容(在这种情况下是椭圆形)。这样,无论何时PasswordBox失去焦点,它都会改变回椭圆形。我认为这比有时看到弹珠字符有时看到空白更好。David Edey的DataGrid_PreparingCellForEdit函数完美地解决了双击问题。
以下是我的数据模板。
<Grid.Resources>
<DataTemplate x:Key="PasswordTemplate" >
<Label BorderThickness="0" Height="23" HorizontalAlignment="Stretch" Content="..."/>
</DataTemplate>
<DataTemplate x:Key="EditingPasswordTemplate" >
<PasswordBox PasswordChanged="PasswordBox_PasswordChanged" BorderThickness="0"
Height="23" HorizontalAlignment="Stretch" />
</DataTemplate>
</Grid.Resources>