none
WinForm TreeView => WPF Window RRS feed

  • Frage

  • Ich habe eine WinForm-Anwendung, die ein TreeView-Control verwendet. Im AfterLabelEdit-Eventhandler wird die Eingabe geprüft und ggf. eine Meldung angezeigt, die auf den Eingabefehler hinweist. Dieses Fenster ist in WPF gebaut und besitzt einen Button, der das Fenster wieder zumacht. Daher ist dieser mit IsDefault="true" definiert.

    Nun zeigt sich folgendes, unschönes Verhalten: Wird die Eingabe durch Klicken mit der Maus beendet (LostFocus), so erscheint das Fenster und man kann die Meldung lesen und per OK-Button das Fenster wieder schließen. Wird jedoch die Eingabe durch die Enter-Taste beendet, die blitzt das Fenster für einen Winpernschag auf und verschwindet sofort wieder, da der Anschalg auf die Entertaste offenbar noch nicht verarbeitet wurde.

    Frage:

    Wie kann man dieses unschöne Verhalten ändern?

    // In der WinForm-Klasse:
    private void treeView1_AfterLabelEdit(object sender, NodeLabelEditEventArgs e)
    {
    	ExceptionMessageBox.Show();
    }
    <Window x:Class="MysticTreeControl.ExceptionMessageBox"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Height="234" Width="520">
        
        <Grid>
            <Button Content="_OK" 
    				Height="23"
    				Width="75"
    				HorizontalAlignment="Center" 
    				VerticalAlignment="Center"  
    				Click="okButton_Click"
    				IsDefault="True" />
        </Grid>
    	
    </Window>

    public partial class ExceptionMessageBox : Window
    {
    	private ExceptionMessageBox()
    	{
    		this.InitializeComponent();
    	}
    
    	public static void Show()
    	{
    		ExceptionMessageBox box = new ExceptionMessageBox();
    		box.ShowDialog();
    	}
    
    	private void okButton_Click(object sender, RoutedEventArgs e)
    	{
    		this.Close();
    	}
    }


    Mittwoch, 14. Dezember 2016 09:57

Antworten

  • Hallo Lars,

    ich konnte dein Problem erfolgreich nachbilden. Das was du da entdeckt hast ist schon ein wenig seltsam. Was ich beobachten konnte:

    1. Das WPF Fenster wird durch das Drücken der Enter-Taste geschlossen.
    2. Die Key-Events werden nicht vom WPF Fenster registriert (Kein KeyDown, KeyUp oder die PreviewVersionen davon)
      Trotzdem wird das Closing-Event aufgerufen.
    3. Wenn ich im Loaded-Event 500ms warte und wärend dessen das schließen des WPF Fensters verhindere, wird noch PreviewKeyUp für Enter aufgerufen.

    Eine wirkliche Lösung habe ich für dein Problem leider auch nicht, lediglich einen bei mir funktionierenden Workaround. Dieser verhindert in den ersten 500ms das Schließen des WPF Fensters.

    bool _canClosed = false;
    
    private async void MyWpfWindow_Loaded(object sender, RoutedEventArgs e)
    {
        await Task.Delay(500);
        _canClosed = true;
    }
    
    private void MyWpfWindow_Closing(object sender, CancelEventArgs e)
    {
        if (!_canClosed)
        {
            e.Cancel = true;
        }
    }


    Tom Lambert - .NET (C#) MVP
    Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
    Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
    Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets

    Mittwoch, 14. Dezember 2016 13:49
    Moderator

Alle Antworten

  • Hallo Lars,

    ich konnte dein Problem erfolgreich nachbilden. Das was du da entdeckt hast ist schon ein wenig seltsam. Was ich beobachten konnte:

    1. Das WPF Fenster wird durch das Drücken der Enter-Taste geschlossen.
    2. Die Key-Events werden nicht vom WPF Fenster registriert (Kein KeyDown, KeyUp oder die PreviewVersionen davon)
      Trotzdem wird das Closing-Event aufgerufen.
    3. Wenn ich im Loaded-Event 500ms warte und wärend dessen das schließen des WPF Fensters verhindere, wird noch PreviewKeyUp für Enter aufgerufen.

    Eine wirkliche Lösung habe ich für dein Problem leider auch nicht, lediglich einen bei mir funktionierenden Workaround. Dieser verhindert in den ersten 500ms das Schließen des WPF Fensters.

    bool _canClosed = false;
    
    private async void MyWpfWindow_Loaded(object sender, RoutedEventArgs e)
    {
        await Task.Delay(500);
        _canClosed = true;
    }
    
    private void MyWpfWindow_Closing(object sender, CancelEventArgs e)
    {
        if (!_canClosed)
        {
            e.Cancel = true;
        }
    }


    Tom Lambert - .NET (C#) MVP
    Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
    Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
    Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets

    Mittwoch, 14. Dezember 2016 13:49
    Moderator
  • Danke für deine Antwort. Auf die Idee einer Totzeit war ich auch schon gekommen, zwar ein wenig anders implementiert aber genauso funktionsfähig. Dieser Workaround/Hack ist irgendwie unbefriedigend aber ich denke, dass ich damit leben werden kann.
    Montag, 19. Dezember 2016 12:11