2016-12-20 3 views
-1

私は次のようにマークアップされたPasswordBoxでログインビューがあります。私のWPFパスワードボックスで何が問題になっていますか?

<PasswordBox x:Name="PasswordText" Width="Auto" Margin="5" PasswordChanged="PasswordTextOnPasswordChanged" /> 

それに伴う問題は、キャレットはそのテキストボックスの左端に残っていることです。入力すると前に移動しないので、入力した最後の文字がテキストボックスの最初の文字になります。例えば。パスワード「123」を入力すると、PasswordBoxのコンテンツは、通常の文字列に変換された後、「321」となります。コンバージョンコードではありません。パスワードを入力した場合、つまりタイプインしない場合、コンテンツは正しいプレーンストリングに変換されます。

ここでは何が起こっていますか?キャレットが入力したものに従わないことは、私にはバギーのようです。舞台裏

(すなわち、コードビハインド)私が持っている:

private void PasswordTextOnPasswordChanged(object sender, RoutedEventArgs e) 
{ 
    if (!_suppressPasswordChanged) 
    { 
     ((LoginFormViewModel)DataContext).Password = PasswordText.SecurePassword; 
    } 
} 

_suppressPasswordChangedは、私は明示的にパスワードを設定するときだけPasswordTextOnPasswordChangedハンドラをトリガ避けるためです。

+1

2 Qs:1)PasswordTextOnPasswordChangedの内容は何ですか? 2)このバグのある動作を確認するために、VM内で実行している可能性はありますか?先日、Parallels VM – Bijington

+0

を実行している誰かと同じような変なタイプの問題が発生し、変更イベントが破られ、スタイルが検査されました。あなたはそれが魚のようなものかどうかを確認してください – Steve

+0

@Profあなたはそれを有効にしたままにしているかもしれません...ちょっと考えてください – CodingYoshi

答えて

0
public void SetPassword(string password) 
{ 
    try 
    { 
     _suppressPasswordChanged = true; 
     PasswordText.Password = password; 
    } 
    finally 
    { 
     _suppressPasswordChanged = false; 
    } 
} 

PasswordBox結合データがないので、その場合ボックスにユーザーがビューモデルを更新するためにビューのコードを必要とします。私はもともと、このイベントハンドラを持っていた:

private void PasswordTextOnPasswordChanged(object sender, RoutedEventArgs e) 
{ 
    ((LoginFormViewModel)DataContext).Password = PasswordText.SecurePassword; 
} 

は、それから私は、ビューモデルにPasswordプロパティを設定できるようにしたかった、とこのビューのメソッドを追加する必要がありました:

セッターから呼び出され
public void SetPassword(string password) 
{ 
    PasswordText.Password = password; 
} 

set 
{ 
    if (value == _password) return; 
    _password = value; 
    ((LoginFormPopup)View).SetPassword(_password.ToClearString()); 
    OnPropertyChanged(); 
} 

それは時に再帰的にトン通常べきではなく、これは、再びセッターと呼ばれるPasswordTextOnPasswordChangedを、トリガSetPasswordになってしまいましたコードによって喚起された。

private bool suppressPasswordChanged; 
private void PasswordTextOnPasswordChanged(object sender, RoutedEventArgs e) 
{ 
    if (!suppressPasswordChanged) 
    { 
     ((LoginFormViewModel)DataContext).Password = PasswordText.SecurePassword; 
    } 
} 

public void SetPassword(string password) 
{ 
    try 
    { 
     suppressPasswordChanged = true; 
     PasswordText.Password = password; 
    } 
    finally 
    { 
     suppressPasswordChanged = false; 
    } 
} 

しかしSetPasswordは常にそのfinallysuppressPasswordChangedをリセットするので、それはまだ常にPasswordTextOnPasswordChangedから呼び出さなるだろう:お互いを呼び出し、これらのメソッドの予防に私の最初のと恥ずかしいの試みでした。

私の、現在の作業が、わずか臭い、解決策は、イベントハンドラに「-呼び出すことはありません」フラグを設定する責任を動かすことであるかもしれない:今

private bool _textChangedEventBusy; 
private void PasswordTextOnPasswordChanged(object sender, RoutedEventArgs e) 
{ 
    try 
    { 
     _textChangedEventBusy = true; 
     ((LoginFormViewModel)DataContext).Password = PasswordText.SecurePassword; 
    } 
    finally 
    { 
     _textChangedEventBusy = false; 
    } 
} 

public void SetPassword(string password) 
{ 
    if (!_textChangedEventBusy) 
    { 
     PasswordText.Password = password; 
    } 
} 

SetPasswordがしか呼ばれていますビューモデルのセッターから取得し、キャレットをテキストの先頭に設定するのが理想的です。

関連する問題