Event priority: LostFocus is called after SelectionChange

1.1k views Asked by At

Evening all, I've run into an issue with the SelectionChanged (TabControl) event being call before the LostFocus (TextBox) event.

This is a problem since the SelectionChanged is triggered during a tab change, that intern resets the ListView.SelectedIndex (TabControl>TabItem>ListView) to -1.

The textbox uses LostFocus to update/validate it's textbox.text which depend upon the SelectedIndex. The text in the textbox is stored/retrieved from a List<string> and because the index changed, the List happens to go out of bounds.

I've looked around, tired a few things also a "hack-y" approach which didn't really help.

<TabControl SelectionChanged="SelectionChanged_Tab"
    <TabItem .../>
    <TabItem .../>
</TabControl>
<Grid>
   <Label .../>
   <TextBox Name="Name" LostFocus="Lost_Focus" .../>
</Grid>

Code:

private void SelectionChanged_Tab(object sender, SelectionChangedEventArgs e)
{
    if (e.Source is TabControl)
    {
        ListView1.SelectedIndex = -1;
        ListView2.SelectedIndex = -1;
    }
}

private void Lost_Focus(object sender, RoutedEventArgs e)
{
    TextBox textbox = sender as TextBox;
    int Index = ListView.SelectedIndex;

    if (string.IsNullOrEmpty(textbox.Text) || textbox.Text == "0")
    {
        textbox.Text = "0";
    }

    switch (textbox.Name)
    {
        case "Name":
            SomeList[Index].AProperty = textbox.Text;
            break;
    }
}
1

There are 1 answers

0
SharkBytes On BEST ANSWER

OK, so after think about the problem from a different perspective, I decided to simple make the TabControl, an Focus-able event and simple make it focus when selection changes:

<TabControl SelectionChanged="SelectionChanged_Tab" Focusable="True"
    <TabItem .../>
    <TabItem .../>
</TabControl>

Code:

private void SelectionChanged_Tab(object sender, SelectionChangedEventArgs e)
{
    if (e.Source is TabControl)
    {
        ListView2.Focus();
        ListView1.SelectedIndex = -1;
        ListView2.SelectedIndex = -1;
    }

    if (ListView2.SelectedIndex == -1)
    {
        ListView1.Focus();
    }
}

I know it's not the most elegant solution (In the process or re-factoring) but this seems to get the job done.