Pourquoi un crash contrôle PasswordBox mon application WPF?
-
27-10-2019 - |
Question
J'ai passé une bonne journée à essayer de comprendre pourquoi le PasswordBox
me cause tant de problèmes.
J'ai une application qui fonctionne sur toutes les machines, je l'ai testé sur. Maintenant, il a été installé sur d'autres machines, il est de s'écraser chaque fois que je clique à l'intérieur du PasswordBox
.
J'ai même fait une application de test avec juste un contrôle TextBox
et PasswordBox
pour voir si l'accident a été causé par un code sous-jacent dans ma demande, mais cela est avéré ne pas être le cas. Je clique sur le TextBox
, et il fonctionne très bien. me permet de taper du texte à l'intérieur. Mais dès que je clique sur le PasswordBox
, bloque l'application.
Je mis en place ces événements pour intercepter toutes les exceptions non gérées:
-
Application.Current.DispatcherUnhandledException
-
AppDomain.CurrentDomain.UnhandledException
-
AppDomain.CurrentDomain.FirstChanceException
Maintenant, cela devrait me montrer un MessageBox
si des erreurs se produisent. Le pire est, est qu'il n'y a pas d'erreurs jetées à ces événements.
Je mis en place une exploitation forestière dans ma demande et je suis des exceptions comme:
- Référence de l'objet n'est pas définie à une instance d'un objet
- Tentative de lecture ou écriture de mémoire protégée. Cela est souvent une indication qu'une autre mémoire est corrompue.
Je l'avais mis en place un événement pour le PasswordBox
à tester si elle a mise au point avant qu'il est écrasé et il l'a fait, donc je ne pense pas que l'exception de référence de l'objet fait référence au contrôle de PasswordBox
.
J'ai cherché partout pour trouver si quelqu'un d'autre a eu ces problèmes et ont vu que des problèmes avec le contrôle de TextBox
et de ses enjeux Focus, qui sont censés être fixés dans .NET 4.0
Oh! et cela me fait penser. J'utilise WPF .NET 4.0.
Toute aide serait grandement appréciée.
Le code de test est:
private void Application_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
Application.Current.DispatcherUnhandledException += new System.Windows.Threading.DispatcherUnhandledExceptionEventHandler((x, y) => { ShowError(x, y); });
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler((x, y) => { ShowError(x, y); });
AppDomain.CurrentDomain.FirstChanceException += new EventHandler<System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs>((x, y) => { ShowError(x, y); });
}
private void ShowError(object sender, object o)
{
Exception ex = null;
if (o.GetType() == typeof(FirstChanceExceptionEventArgs))
{
ex = ((FirstChanceExceptionEventArgs)o).Exception;
}
else if (o.GetType() == typeof(DispatcherUnhandledExceptionEventArgs))
{
ex = ((DispatcherUnhandledExceptionEventArgs)o).Exception;
}
else if (o.GetType() == typeof(UnhandledExceptionEventArgs))
{
ex = (Exception)((UnhandledExceptionEventArgs)o).ExceptionObject;
}
MessageBox.Show(ex.Message + "\n\r" + ex.StackTrace, "Error at: " + ex.Source, MessageBoxButton.OK, MessageBoxImage.Error);
}
Et le XAML:
<Window x:Class="WPF_Control_Test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="200" Width="300">
<Grid>
<StackPanel Orientation="Vertical" HorizontalAlignment="Left">
<StackPanel Orientation="Horizontal" Width="260">
<TextBlock Text="TextBox: " TextAlignment="Right" Width="80" Height="Auto" VerticalAlignment="Center" />
<TextBox Name="textBox" Width="120" VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal" Width="260">
<TextBlock Text="PasswordBox: " TextAlignment="Right" Width="80" Height="Auto" VerticalAlignment="Center" />
<PasswordBox Name="passwordBoxTest" Width="120" VerticalAlignment="Center" />
</StackPanel>
</StackPanel>
</Grid>
</Window>
Observateur d'événements
Voici l'exception de l'Observateur d'événements sur la machine:
Application: WPF contrôle Test.exe
Cadre Version: v4.0.30319
Description: L'application demandée par la fin du processus (string message) System.Environment.FailFast
.
Message:. Erreur système irrécupérable
Stack:
à System.Environment.FailFast (System.String)
à MS.Internal.Invariant.FailFast (System.String, System.String)
à System.Windows.Media.FontFamily.get_FirstFontFamily ()
à System.Windows.Documents.TextSelection.CalculateCaretRectangle (System.Windows.Documents.ITextSelection, System.Windows.Documents.ITextPointer)
à System.Windows.Documents.TextSelection.UpdateCaretStateWorker (System.Object)
à System.Windows.Documents.TextSelection.UpdateCaretState (System.Windows.Documents.CaretScrollMethod)
à System.Windows.Documents.TextSelection.EnsureCaret (booléen, System.Windows.Documents.CaretScrollMethod)
à System.Windows.Documents.TextSelection.System.Windows.Documents.ITextSelection.UpdateCaretAndHighlight ()
à System.Windows.Documents.TextEditor.OnGotKeyboardFocus (System.Object, System.Windows.Input.KeyboardFocusChangedEventArgs)
à System.Windows.Controls.PasswordBox.OnGotKeyboardFocus (System.Windows.Input.KeyboardFocusChangedEventArgs)
à System.Windows.UIElement.OnGotKeyboardFocusThunk (System.Object, System.Windows.Input.KeyboardFocusChangedEventArgs)
à System.Windows.Input.KeyboardFocusChangedEventArgs.InvokeEventHandler (System.Delegate, System.Object)
à System.Windows.RoutedEventArgs.InvokeHandler (System.Delegate, System.Object)
à System.Windows.RoutedEventHandlerInfo.InvokeHandler (System.Object, System.Windows.RoutedEventArgs)
à System.Windows.EventRoute.InvokeHandlersImpl (System.Object, System.Windows.RoutedEventArgs, Boolean)
à System.Windows.UIElement.RaiseEventImpl (System.Windows.DependencyObject, System.Windows.RoutedEventArgs)
à System.Windows.UIElement.RaiseTrustedEvent (System.Windows.RoutedEventArgs)
à System.Windows.UIElement.RaiseEvent (System.Windows.RoutedEventArgs, Boolean)
à System.Windows.Input.InputManager.ProcessStagingArea ()
à System.Windows.Input.InputManager.ProcessInput (System.Windows.Input.InputEventArgs)
à System.Windows.Input.KeyboardDevice.ChangeFocus (System.Windows.DependencyObject, Int32)
à System.Windows.Input.KeyboardDevice.TryChangeFocus (System.Windows.DependencyObject, System.Windows.Input.IKeyboardInputProvider, Boolean, Boolean, Boolean)
à System.Windows.Input.KeyboardDevice.Focus (System.Windows.DependencyObject, Boolean, Boolean, Boolean)
à System.Windows.Input.KeyboardDevice.Focus (System.Windows.IInputElement)
à System.Windows.UIElement.Focus ()
à System.Windows.Documents.TextEditorMouse.MoveFocusToUiScope (System.Windows.Documents.TextEditor)
à System.Windows.Documents.TextEditorMouse.OnMouseDown (System.Object, System.Windows.Input.MouseButtonEventArgs)
à System.Windows.Controls.PasswordBox.OnMouseDown (System.Windows.Input.MouseButtonEventArgs)
à System.Windows.UIElement.OnMouseDownThunk (System.Object, System.Windows.Input.MouseButtonEventArgs)
à System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler (System.Delegate, System.Object)
à System.Windows.RoutedEventArgs.InvokeHandler (System.Delegate, System.Object)
à System.Windows.RoutedEventHandlerInfo.InvokeHandler (System.Object, System.Windows.RoutedEventArgs)
à System.Windows.EventRoute.InvokeHandlersImpl (System.Object, System.Windows.RoutedEventArgs, Boolean)
à System.Windows.UIElement.RaiseEventImpl (System.Windows.DependencyObject, System.Windows.RoutedEventArgs)
à System.Windows.UIElement.RaiseTrustedEvent (System.Windows.RoutedEventArgs)
à System.Windows.UIElement.RaiseEvent (System.Windows.RoutedEventArgs, Boolean)
à System.Windows.Input.InputManager.ProcessStagingArea ()
à System.Windows.Input.InputManager.ProcessInput (System.Windows.Input.InputEventArgs)
à System.Windows.Input.InputProviderSite.ReportInput (System.Windows.Input.InputReport)
à System.Windows.Interop.HwndMouseInputProvider.ReportInput (IntPtr, System.Windows.Input.InputMode, Int32, System.Windows.Input.RawMouseActions, Int32, Int32, Int32)
à System.Windows.Interop.HwndMouseInputProvider.FilterMessage (IntPtr, MS.Internal.Interop.WindowMessage, IntPtr, IntPtr, Boolean ByRef)
à System.Windows.Interop.HwndSource.InputFilterMessage (IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)
à MS.Win32.HwndWrapper.WndProc (IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)
à MS.Win32.HwndSubclass.DispatcherCallbackOperation (System.Object)
à System.Windows.Threading.ExceptionWrapper.InternalRealCall (System.Delegate, System.Object, Int32)
à MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen (System.Object, System.Delegate, System.Object, Int32, System.Delegate)
à System.Windows.Threading.Dispatcher.InvokeImpl (System.Windows.Threading.DispatcherPriority, System.TimeSpan, System.Delegate, System.Object, Int32)
à MS.Win32.HwndSubclass.SubclassWndProc (IntPtr, Int32, IntPtr, IntPtr)
à MS.Win32.UnsafeNativeMethods.DispatchMessage (System.Windows.Interop.MSG ByRef)
à System.Windows.Threading.Dispatcher.PushFrameImpl (System.Windows.Threading.DispatcherFrame)
à System.Windows.Threading.Dispatcher.PushFrame (System.Windows.Threading.DispatcherFrame)
à System.Windows.Application.RunDispatcher (System.Object)
à System.Windows.Application.RunInternal (System.Windows.Window)
à System.Windows.Application.Run (System.Windows.Window)
à System.Windows.Application.Run ()
à WPF_Control_Test.App.Main ()
La solution
Il semble que le Net Framework est incapable de trouver une police par défaut appropriée. Je ne sais pas pourquoi cela se passe, mais les lignes de interne Code de FontFamily
suivant incorporez la ligne où l'exception est levée:
fontFamily = this.FindFirstFontFamilyAndFace(
ref normal, ref normal2, ref normal3);
if (fontFamily == null)
{
// NullFontFamilyCanonicalName
// = CanonicalFontFamilyReference.Create(null, "#ARIAL");
fontFamily = FontFamily.LookupFontFamily(
FontFamily.NullFontFamilyCanonicalName);
Invariant.Assert(fontFamily != null); // <- Your exception
}
Apparemment, si vous ne spécifiez pas de la police, il va chercher une police basée Arial, qu'il ne peut pas trouver sur cette machine, donc votre exception.
Autres conseils
J'ai eu ce même problème sur une boîte Windows Embedded 7, et comme indiqué dans le lien des commentaires;
http: // sociale. msdn.microsoft.com/Forums/ar/wpf/thread/fc2c9a54-8f66-4f1a-82be-cb40ada5fba5
J'ai simplement copié à travers les polices suivantes du « c: \ windows » de polices de répertoire, et le problème a été résolu;
- Arial (TrueType)
- Courier New (TrueType)
- Times New Roman (TrueType)