Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么WPF密码框有时变为空白,而其他密码框则变为空白?_C#_Wpf_Passwordbox - Fatal编程技术网

C# 为什么WPF密码框有时变为空白,而其他密码框则变为空白?

C# 为什么WPF密码框有时变为空白,而其他密码框则变为空白?,c#,wpf,passwordbox,C#,Wpf,Passwordbox,我包括了一个示例程序:似乎在切换到密码框时,输入文本并进行切换会导致密码框变为空白。但是双击密码框,输入文本并跳出并不能。为什么会发生这种情况 编辑:我发现文本框也会出现这种情况,所以它不是PasswordBox特有的错误 重新创建每个场景的步骤: 使密码消失 单击新建 单击“名字”字段 打字 按TAB键 打字 按TAB键 按TAB键(yes两次,否则将触发Save事件) 打字 注意点而不是文本-PasswordBox正在工作 按TAB键 当密码箱变为空白时,让您的朋友感到惊讶 使密码不消失

我包括了一个示例程序:似乎在切换到密码框时,输入文本并进行切换会导致密码框变为空白。但是双击密码框,输入文本并跳出并不能。为什么会发生这种情况

编辑:我发现文本框也会出现这种情况,所以它不是PasswordBox特有的错误

重新创建每个场景的步骤:

使密码消失
  • 单击新建
  • 单击“名字”字段
  • 打字
  • 按TAB键
  • 打字
  • 按TAB键
  • 按TAB键(yes两次,否则将触发Save事件)
  • 打字
  • 注意点而不是文本-PasswordBox正在工作
  • 按TAB键
  • 当密码箱变为空白时,让您的朋友感到惊讶
使密码不消失
  • 单击新建
  • 单击“名字”字段
  • 打字
  • 按TAB键
  • 打字
  • 双击密码字段
  • 打字
  • 注意点而不是文本-PasswordBox正在工作
  • 按TAB键
  • 让你的朋友感到惊奇的是。。等等,密码箱不是空的?WTF
示例代码:

使用系统;
使用System.Collections.ObjectModel;
命名空间WpfApplication1{
公共密封类MyData{
私有可观察收集数据列表;
公共ObservableCollection数据列表{get{return DataList;}}
public MyData(){dataList=newobserveCollection();}
public void AddBlankRow(){DataList.Add(new MyDataRow(this));}
}
公共密封类MyDataRow{
私有只读MyData MyData;
公共MyDataRow(MyData MyData){this.MyData=MyData;}
公共字符串名{get;set;}
公共字符串LastName{get;set;}
公共字符串密码{get;set;}
}
}
使用制度;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Input;
命名空间WpfApplication1{
公共部分类主窗口:窗口{
私有MyData数据{get{return(MyData)DataContext;}}
公共主窗口(){InitializeComponent();}
私有无效密码箱\u密码已更改(对象发送方,RoutedEventArgs e){
密码箱pb=(密码箱)发送方;
如果(pb!=null){
MyDataRow row=pb.DataContext作为MyDataRow;
如果(row!=null){row.Password=pb.Password;}
}
}
私有无效窗口_已加载(对象发送方,RoutedEventArgs e){DataContext=new MyData();}
私有无效窗口\正在关闭(对象发送方,System.ComponentModel.CancelEventArgs e){}
私有void SaveExecute(对象发送方,ExecutedRoutedEventArgs e){}
私有void NewExecute(对象发送方,ExecutedRoutedEventArgs e){Data.AddBlankRow();}
私有void CancelExecute(对象发送方,ExecutedRoutedEventArgs e){Close();}
}
}
编辑 使用CellTemplate和EditingCellTemplate的数据模板, 我的工作只是保持一致——总是展示一些东西(在本例中是一个省略)。这样,不管怎样,当密码箱失去焦点时,它会变回elipse。我认为这比有时看到子弹字符,有时看到空白要好。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>

我认为这个问题与两个独立的模板有关:一个用于编辑(
CellEditingTemplate
),另一个用于显示(
CellTemplate
)。通常的解决方法是使用绑定,并使两个单独的模板都绑定到同一数据段,如下所示:

但是,出于安全原因,
PasswordBox
当然不允许您绑定到
Password
(因为
Password
不是依赖属性)。如果这不是一个很大的问题(我不完全理解为什么会这样,但我想他们不希望明文密码在绑定中四处飞来飞去,而没有人知道他们在做什么),那么您可以按照本文的下半部分创建绑定:-使用自定义静态依赖属性

因此,我在下面的代码中实现了这一过程,并且通过向
PreparingCellForEdit
事件添加一个处理程序,修复了密码框没有正确聚焦并且需要两个选项卡的错误,如

总之,我的工作示例的示例代码是:

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;
using System.Windows.Media;

namespace WpfApplication1 {
    public partial class MainWindow : Window
    {
        public MainWindow() { InitializeComponent(); }
        private MyData Data { get { return (MyData)DataContext; } }

        void DataGrid_PreparingCellForEdit(object sender, DataGridPreparingCellForEditEventArgs e)
        {
            var inputElement = VisualTreeHelper.GetChild(e.EditingElement, 0) as PasswordBox;
            if (inputElement != null)
            {
                Keyboard.Focus(inputElement);
            }
        }

        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(); }
    }
使用系统;
使用System.Collections.ObjectModel;
命名空间WpfApplication1{
公共密封类MyData{
私有可观察收集数据列表;
公共ObservableCollection数据列表{get{return DataList;}}
public MyData(){dataList=newobserveCollection();}
public void AddBlankRow(){DataList.Add(new MyDataRow(this));}
}
公共密封类MyDataRow{
私有只读MyData MyData;
公共MyDataRow(MyData MyData){this.MyData=MyData;}
公共字符串名{get;set;}
公共字符串LastName{get;set;}
公共字符串密码{get;set;}
}
}
使用制度;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Input;
使用System.Windows.Media;
命名空间WpfApplication1{
公共部分类主窗口:窗口
{
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;
using System.Windows.Media;

namespace WpfApplication1 {
    public partial class MainWindow : Window
    {
        public MainWindow() { InitializeComponent(); }
        private MyData Data { get { return (MyData)DataContext; } }

        void DataGrid_PreparingCellForEdit(object sender, DataGridPreparingCellForEditEventArgs e)
        {
            var inputElement = VisualTreeHelper.GetChild(e.EditingElement, 0) as PasswordBox;
            if (inputElement != null)
            {
                Keyboard.Focus(inputElement);
            }
        }

        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"
        xmlns:w="clr-namespace:WpfApplication1"
        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, Mode=OneTime}" ColumnWidth="*" Margin="10,0,9,38" HorizontalAlignment="Stretch"
                  AutoGenerateColumns="False" GridLinesVisibility="Horizontal"
                  HeadersVisibility="Column" HorizontalGridLinesBrush="LightGray" CanUserReorderColumns="False" Background="White"
                  PreparingCellForEdit="DataGrid_PreparingCellForEdit">
            <DataGrid.Resources>
                <DataTemplate x:Key="PasswordTemplate">
                    <PasswordBox w:PasswordHelper.Attach="True" w:PasswordHelper.Password="{Binding Password, Mode=TwoWay}" 
                                 BorderThickness="0" Height="23" HorizontalAlignment="Stretch" Width="130" />
                </DataTemplate>
            </DataGrid.Resources>
            <DataGrid.Columns>
                <DataGridTextColumn Header="First Name"  Binding="{Binding FirstName}"/>
                <DataGridTextColumn Header="Last Name"  Binding="{Binding LastName}"/>
                <DataGridTemplateColumn Header="Password" CellTemplate="{StaticResource PasswordTemplate}"
                                        CellEditingTemplate="{StaticResource PasswordTemplate}" />
            </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>