Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
TextBox.Focus() führt zu einer StackOverflowException
Xalir
myCSharp.de - Member



Dabei seit:
Beiträge: 9

Themenstarter:

TextBox.Focus() führt zu einer StackOverflowException

beantworten | zitieren | melden

Hallo,

ich habe in einer WPF-Anwendung eine TextBox, die validiert werden muss. Die Validierung soll stattfinden, sobald die TextBox den Fokus verliert und mit txt.Focus() und txt.SelectAll() der fehlerhafte Inhalt markiert werden.

Soweit so gut, in meiner Anwendung ist das nachfolgende Control eine ComboBox. Wenn ich jetzt eine fehlerhafte Eingabe provoziere, führt der Fokus zu einer StackOverflowException, da die ComboBox jedesmal sich den Fokus wiederholt.

Hier die Controlvorlage:
<ControlTemplate x:Key="SplitTemplate">
  <Expander IsExpanded="True" IsTabStop="False">
    <Grid>
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="Auto" />
      </Grid.ColumnDefinitions>
      <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
      </Grid.RowDefinitions>
      <Label />
      <TextBox Grid.Column="1" />
      <Label Grid.Row="1" Content="Rassenrestriktion" />
      <ComboBox Grid.Column="1" Grid.Row="1" SelectedIndex="0"
            ItemsSource="{Binding Source={StaticResource Races}, XPath=Race/Language}" />
      <Label Grid.Row="2" Content="Rollenrestriktion" />
      <ComboBox Grid.Column="1" Grid.Row="2" SelectedIndex="0"
            ItemsSource="{Binding Source={StaticResource Roles}, XPath=Role}" />
      <Label Grid.Row="3" Content="Attributsrestriktion" />
      <ComboBox Grid.Column="1" Grid.Row="3" Name="cmbGeneralAttributeRestriction1" SelectedIndex="0"
            ItemsSource="{Binding Source={StaticResource Attributes}, XPath=Attribute}" />
    </Grid>
  </Expander>
</ControlTemplate>

Ich lade die Controlvorlage und weise der TextBox ein LostFocus-EventHandler zu.

Mein EventHandler sieht so aus

private void txt_LostFocus(object sender, RoutedEventArgs e)
{
    var txt = sender as TextBox;
    int UnitsInSplit;
    int TotalUnits;
    bool IsGeneral;
    StackPanel pnl;
            
    if(txt.Text.Length==0)
    {
        return;
    }

    int.TryParse(txt.Text, out UnitsInSplit);

    if ((((txt.Parent as Grid).Parent as Expander).Parent as StackPanel)
        .Name.Contains("General"))
    {
        int.TryParse(txtGenerals.Text, out TotalUnits);
        pnl = pnlGeneralSplit;
        IsGeneral = true;
    }
    else
    {
        int.TryParse(txtTroops.Text, out TotalUnits);
        pnl = pnlTroopSplit;
        IsGeneral = true;
    }

    var Position = pnl.Children.IndexOf((txt.Parent as Grid).Parent
        as Expander);

    if (UnitsInSplit > TotalUnits)
    {
        txt.Focus();
        txt.SelectAll();
    }

    if (UnitsInSplit < TotalUnits && Position == pnl.Children.Count - 1)
    {
        CreateNewSplit(pnl, IsGeneral);
        return;
    }            
}

Ich habe zumindest das Problem soweit eingrenzen können, dass es auftritt, wenn ich mit der Tastatur navigiere. Wechsle ich den Fokus mit der Maus, tritt keine StackOverflowException auf. Hat jemand eine Idee, woran dies liegt und wie ich den Fehler beheben kann?
private Nachricht | Beiträge des Benutzers
MrSparkle
myCSharp.de - Team

Avatar #avatar-2159.gif


Dabei seit:
Beiträge: 5.655
Herkunft: Leipzig

beantworten | zitieren | melden

Hi Xalir,

das könntest du aber sehr einfach selbst herausfinden, indem du einen Breakpoint in die Methode setzt und mit Einzelschritt-Debugging durchgehst, um zu schauen, was passiert. Im Stacktrace der Exception stehen auch die Methodenaufrufe drin, da siehst du bestimmt, daß es sich um rekursive Aufrufe handelt.

Christian
Weeks of programming can save you hours of planning
private Nachricht | Beiträge des Benutzers
Xalir
myCSharp.de - Member



Dabei seit:
Beiträge: 9

Themenstarter:

beantworten | zitieren | melden

Hi MrSparkle,

Einzelschritt-Debugging habe ich gemacht. Der StackTrace erzählt mir folgendes: "Der Ausdruck kann nicht ausgewertet werden, weil sich der Thread in einem Stapelüberlauf befindet."

Zu Debugging-Zwecken habe ich bei der ComboBox ein GotFocus-Event hinzugefügt. Nun weiß ich zwar, dass etwas schief läuft, aber ich komme dennoch nicht weiter. Wie gesagt, die Exception wird nur dann gefeuert, wenn ich über die Tab-Taste navigiere. Mit der Maus gibt es keine Probleme.
private Nachricht | Beiträge des Benutzers
MrSparkle
myCSharp.de - Team

Avatar #avatar-2159.gif


Dabei seit:
Beiträge: 5.655
Herkunft: Leipzig

beantworten | zitieren | melden

Zitat von Xalir
Einzelschritt-Debugging habe ich gemacht.

Dann weißt du ja jetzt, wie der Programm-Ablauf ist, bevor die Exception eintritt.
Zitat von Xalir
Nun weiß ich zwar, dass etwas schief läuft

...behältst es aber für dich
Zitat von Xalir
aber ich komme dennoch nicht weiter.

Wo genau kommst du nicht weiter? Was genau ist das Problem?
Weeks of programming can save you hours of planning
private Nachricht | Beiträge des Benutzers
Xalir
myCSharp.de - Member



Dabei seit:
Beiträge: 9

Themenstarter:

beantworten | zitieren | melden

Zitat von MrSparkle
Dann weißt du ja jetzt, wie der Programm-Ablauf ist, bevor die Exception eintritt.
Ablauf ist wie folgt:

txt_LostFocus wird ausgelöst beim Verlassen des Fokus. Es geht in den von mir geposteten Programmteil. Die Überprüfung findet statt, txt.Focus() und txt.SelectAll() wird ausgeführt. Sobald dass passiert, tritt ComboBox_GotFocus ein und txt_LostFocus wird wieder ausgeführt. Somit führt es zur Endlosschleife.

Zwischen den beiden Ereignissen wird kein weiterer Code ausgeführt, der Debugger springt sofort wieder nach txt_LostFocus.
Zitat von MrSparkle
Wo genau kommst du nicht weiter? Was genau ist das Problem?
Das Problem ist, die ComboBox holt sich aus Gründen, die ich nicht kenne und wo ich das Problem nicht näher eingrenzen kann, den Fokus immer und immer wieder. Kein Programmcode von meiner Seite löst das Ereignis aus. Ich möchte herausfinden, was denn das GotFocus-Ereignis auslöst (Abgesehen von dem einmaligen Fokus setzen über die Tab-Navigation).
private Nachricht | Beiträge des Benutzers
MrSparkle
myCSharp.de - Team

Avatar #avatar-2159.gif


Dabei seit:
Beiträge: 5.655
Herkunft: Leipzig

beantworten | zitieren | melden

Zitat von Xalir
Das Problem ist, die ComboBox holt sich aus Gründen, die ich nicht kenne und wo ich das Problem nicht näher eingrenzen kann, den Fokus immer und immer wieder.

Weil du es so programmiert hast:
Zitat von Xalir
Die Überprüfung findet statt, txt.Focus() und txt.SelectAll() wird ausgeführt. Sobald dass passiert, tritt ComboBox_GotFocus ein und txt_LostFocus wird wieder ausgeführt.

Wenn du im LostFocus-EventHandler die Focus-Methode aufrufst, dann ist es alles andere als verwunderlich, daß die Textbox den Focus bekommen, oder?

Christian
Weeks of programming can save you hours of planning
private Nachricht | Beiträge des Benutzers
Xalir
myCSharp.de - Member



Dabei seit:
Beiträge: 9

Themenstarter:

beantworten | zitieren | melden

Anscheinend stehe ich auf den Schlauch, denn ich verstehe Deine Aussage nicht. Die TextBox soll ja den Fokus wiederbekommen, wenn eine Fehleingabe auftritt. Aber was hat der Fokus der TextBox mit dem Fokus der ComboBox zu tun? Ich verweise ja auf die TextBox und nicht auf die ComboBox.

Edit: Ja, ja jetzt macht Deine Aussage Sinn. Ja, Du hast recht. Ich bin in meinem Denken gefangen gewesen. Jetzt fällt es mir wie Schuppen vor die Augen
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Xalir am .
private Nachricht | Beiträge des Benutzers
Xalir
myCSharp.de - Member



Dabei seit:
Beiträge: 9

Themenstarter:

beantworten | zitieren | melden

So, nach etlichen Hin und Her bin ich jetzt zur Lösung gekommen. Es lag nicht an einer falschen Programmierung.


txt.SelectAll();
Application.Current.Dispatcher.BeginInvoke(new Action(() => txt.Focus()));

Dies löst mein Problem mit der Endlosschleife.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Xalir am .
private Nachricht | Beiträge des Benutzers
chavez
myCSharp.de - Member



Dabei seit:
Beiträge: 252
Herkunft: Österreich

beantworten | zitieren | melden

Trotzdem solltest du nicht mehrere Foren gleichzeitig "belästigen". siehe [Hinweis] Wie poste ich richtig? 2.2
Crosspost
private Nachricht | Beiträge des Benutzers