none
.Focus() und Keyboard.Focus() zeigen keine Wirkung RRS feed

Antworten

  • Hallo Frank,
    in der TestPage.xaml.cs prüfst du ein die Control in Zeile 91 und 92 darauf ob es ein Label ist (typeof(Label) liefert übrigens das Selbe wie new Label().GetType() und ist der ursprünglich angedachte Weg dafür).

    Das ist das erste Problem. Du legst den Fokus auf das Label und nicht auf das erste Eingabeelement.
    Das 2. Problem ist, das der ScrollViewer sich aus irgend einem Grund immer und immer wieder den Fokus nimmt. Das Ganze geht aber, indem man per Dispatcher und Invoke den Fokus setzt. Damit wird einfach nur die Reihenfolge der Abarbeitung der Befehle geändert - aber es hilft.

    Ich habe deinen Code nun wie folgt abgeändert:

    static Type[] InputControls = { typeof(TextBox), typeof(Button), typeof(CheckBox), typeof(RadioButton), typeof(ToggleButton) };//Controls
    
    private void POPUP_LABEL_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        Label lblMouseEnter = (Label)sender;
        string labelName = lblMouseEnter.Content.ToString();
        foreach (Border brd in Helper.FindVisualChild.All<Border>(wpnContent))
        {
            if (brd.Visibility == Visibility.Visible)
            {
                Label lbl = Helper.FindVisualChild.First<Label>(brd);
                if (lbl != null && lbl.Content.ToString().Equals(labelName))
                {
                    foreach (Control ctr in Helper.FindVisualChild.All<Control>(brd))
                    {
                        if (ctr.Visibility == Visibility.Visible)
                        {
                            //Contains ist eine LINQ Erweiterungsmethode
                            //Entsprechenden Namespace importieren:
                            //using System.Linq;
                            //Damit wird geprüft, ob der Typ des Controls ein Eingabecontrol ist
                            if (InputControls.Contains(ctr.GetType()))
                            {
                                this.Dispatcher.BeginInvoke(DispatcherPriority.Background, new ThreadStart(() =>
                                {
                                    popUp.IsOpen = false;
                                    ctr.Focus();
                                }));
                                return;//Auch die äußere Schleife mit beenden
                            }
                        }
                    }
                }
            }
        }
    }
    In meinem Test funktionierte es dann.


    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

    • Als Antwort markiert frank me Donnerstag, 8. Januar 2015 09:13
    Mittwoch, 7. Januar 2015 19:26
    Moderator

Alle Antworten

  • Wie erkennst du denn, ob das Element den Fokus hat?

    Du kannst Elementen wie der TextBox oder einem Button sehr wohl den Fokus mit .Focus() geben.

    Zur Not schau dir mal die Focusable-Eigenschaft an, die besagt, ob das Element den Fokus haben kann.


    © 2015 Thomas Roskop

    Mittwoch, 7. Januar 2015 14:22
  • @Thomas

    Ich lege den Fokus z.Bsp. auf eine Textbox. Ich würde nun erwarten, dass wenn ich auf meiner Tastatur tippe direkt in die Textbox schreibe, was aber nicht passiert.
    Eine Textbox kann eindeutig einen Fokus besitzen.

    Außerdem, wenn ich die Tab-Taste betätige, dann wandert der Fokus in das erste Control der Page, einem Button (sichtbar anhand der Bottonfärbung).


    www.energiewende-mach-ich-selbst.de

    Mittwoch, 7. Januar 2015 14:27
  • Hallo Frank,
    normalerweise funktioniert das auch so, wie von dir erwartet. Auch in einem kurzen Test hatte ich damit keine Probleme.

    Wie genau ist denn dein Fenster aufgebaut? Das heißt, sind noch andere Controls direkt in deinem Fenster, hat der Frame (in dem die Seite angezeigt wird) die Navigationsleiste eingeblendet und wie ist die Seite selbst beschaffen?

    Setzt du vielleicht doch den Fokus schon irgend wo anders in deinem Code? Zu welchem Zeitpunkt versuchst du aktuell die Focus-Methode aufzurufen?

    Wenn es dir darum geht, das standardmäßig fokusierte Element zu festzulegen, kann dies auch über XAML geschen. Setze dazu in der Page die folgende angefügte Eigenschaft:

    FocusManager.FocusedElement="{Binding ElementName=myTextBox}"
    myTextBox ist dabei das zu fokussierende Control.


    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, 7. Januar 2015 14:41
    Moderator
  • Hi Tom,

    ich habe eine Page, darin ein Grid, darin ein ScrollViewer, darin ein StackPanel, 
    jetzt wird es interessant:
    im StackPannel befindet sich ein Popup, darin befindet sich Border / StackPanel / viele Labels (Liste von Überschriften).
    Bei Klick auf ein Label (MouseLeftButtonDown) soll ein bestimmtes Control aus dem äußeren StackPanel fokussiert werden, so dass man direkt mit der Tastatur im Control weiterarbeiten kann. 
    Es handelt sich jeweils um das erste (fokusierbare) Control eines Bereiches (Border/StackPanel/ viele Controls)
    Die fokussierten Controls können TextBoxen, RadioButton, CheckBoxen, Combobox, Button oder NumericUpDown(eigenes UserControl) sein.

    Zwar gebe ich den Fokus auf ein Control (im Sinne von...)

    Control ctr = new Control();
    ctr.Focus();
    ctr habe ich beim Fokusieren bereits ein bestimmtes Control aus meiner Gui zugewiesen.
    Außerdem habe ich testweise auch myTextBox.Focus() versucht, was aber auch nicht funktioniert.


    Helfen diese Informationen weiter?


    www.energiewende-mach-ich-selbst.de

    Mittwoch, 7. Januar 2015 14:59
  • Hallo Frank,

    ich habe deine Anwendung nochmal teilweise nachgebaut, kann jedoch noch immer keine Probleme feststellen.

    Ich gehe mal davon aus, das das new Control(); in deinem Code Snippet nur ein Beispiel war und du in Wahrheit ein bereits angezeigtes Control abrufst. Denn sichtbar muss ein Control sein, sonst funktioniert das Fokussieren nicht.

    Vom jetzigen Standpunkt aus weiß ich auch nicht mehr, wo das Problem noch liegen könnte. Kannst du vielleicht diene Projektmappe hochladen und den Link hier Teilen oder ggf. das Problem in einem neuen Projekt reproduzieren? Ich schaffe das ja leider nicht.


    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, 7. Januar 2015 15:47
    Moderator
  • Hier ein Link zu einem Testprojekt.
    Lade es runter, entpacken, starten.

    Jetzt gehe mit der Maus auf das Menüsymbol oben rechts.
    Suche einen Menüpunkt aus und klick darauf.

    Jetzt sollte der Fokus auf dem ersten fokussierbaren Control im zugehörigen (markierten) Fensterchen liegen.

    In TestPage.xaml.cs Zeile 94 findet die Zuweisung statt.

    Frank


    www.energiewende-mach-ich-selbst.de

    Mittwoch, 7. Januar 2015 17:32
  • Hallo Frank,
    in der TestPage.xaml.cs prüfst du ein die Control in Zeile 91 und 92 darauf ob es ein Label ist (typeof(Label) liefert übrigens das Selbe wie new Label().GetType() und ist der ursprünglich angedachte Weg dafür).

    Das ist das erste Problem. Du legst den Fokus auf das Label und nicht auf das erste Eingabeelement.
    Das 2. Problem ist, das der ScrollViewer sich aus irgend einem Grund immer und immer wieder den Fokus nimmt. Das Ganze geht aber, indem man per Dispatcher und Invoke den Fokus setzt. Damit wird einfach nur die Reihenfolge der Abarbeitung der Befehle geändert - aber es hilft.

    Ich habe deinen Code nun wie folgt abgeändert:

    static Type[] InputControls = { typeof(TextBox), typeof(Button), typeof(CheckBox), typeof(RadioButton), typeof(ToggleButton) };//Controls
    
    private void POPUP_LABEL_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        Label lblMouseEnter = (Label)sender;
        string labelName = lblMouseEnter.Content.ToString();
        foreach (Border brd in Helper.FindVisualChild.All<Border>(wpnContent))
        {
            if (brd.Visibility == Visibility.Visible)
            {
                Label lbl = Helper.FindVisualChild.First<Label>(brd);
                if (lbl != null && lbl.Content.ToString().Equals(labelName))
                {
                    foreach (Control ctr in Helper.FindVisualChild.All<Control>(brd))
                    {
                        if (ctr.Visibility == Visibility.Visible)
                        {
                            //Contains ist eine LINQ Erweiterungsmethode
                            //Entsprechenden Namespace importieren:
                            //using System.Linq;
                            //Damit wird geprüft, ob der Typ des Controls ein Eingabecontrol ist
                            if (InputControls.Contains(ctr.GetType()))
                            {
                                this.Dispatcher.BeginInvoke(DispatcherPriority.Background, new ThreadStart(() =>
                                {
                                    popUp.IsOpen = false;
                                    ctr.Focus();
                                }));
                                return;//Auch die äußere Schleife mit beenden
                            }
                        }
                    }
                }
            }
        }
    }
    In meinem Test funktionierte es dann.


    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

    • Als Antwort markiert frank me Donnerstag, 8. Januar 2015 09:13
    Mittwoch, 7. Januar 2015 19:26
    Moderator
  • Wow, funktioniert! :-)

    Danke Tom!

    Übrigens habe ich nicht abgefragt ob das Control ein Label ist und dann den Fokus auf das Label gesetzt, sondern ich habe abgefragt, ob das Control KEIN Label ist

    if (ctr.GetType()  !=  new Label().GetType())

    In sofern funktioniert es auch wie gewünscht.

    Ein Problem habe ich noch mit dem Fokus auf mein UserControl, aber dafür werde ich einen neuen Thread eröffnen. 

    Herzliche Grüße,
    Frank


    www.energiewende-mach-ich-selbst.de



    • Bearbeitet frank me Donnerstag, 8. Januar 2015 09:45
    Donnerstag, 8. Januar 2015 09:44