Вопрос

Trying to implement a simple HTML editor TextBox. I have a UserControl with a Canvas as main container and a TextBox and ListBox as its children. The ListBox is invisible by default. When user presses CTRL + SPACE, the ListBox should appear at TextBox's current caret position and focus should be transferred to it, just like Visual Studios's List Members feature. User then selects an item from the list and presses ENTER and the selected item is inserted into the TextBox. The ListBox then becomes invisible again and focus transfers back to the TextBox.

The following code lets me do all of the above; almost. It only works for the first time! The next time I press CTRL + ENTER, the ListBox appears and seems to have focus too, but pressing down (or up) arrow moves focus back to the TextBox, thus moving the caret instead. What's wrong here?

private void txt_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
    if (e.Key == Key.Space && (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
    {
        var Rect = txt.GetRectFromCharacterIndex(txt.SelectionStart , true);
        Canvas.SetLeft(lst, Rect.Right);
        Canvas.SetTop(lst, Rect.Bottom);

        lst.Visibility = System.Windows.Visibility.Visible;
        lst.Focus();
    }

}

private void lst_KeyDown(object sender, KeyEventArgs e)
{
    if(e.Key == Key.Enter)
    {
        txt.Focus();
        lst.Visibility = System.Windows.Visibility.Hidden;
        txt.SelectedText = lst.SelectedItem.ToString();
        txt.SelectionStart += lst.SelectedItem.ToString().Length;
        txt.SelectionLength = 0;
    }
}
Это было полезно?

Решение

I was able to duplicate your problem, It appears that the focus in not being assigned to your listbox and is remaining in the TextBox. I was able to get it to work by using the textbox's MoveFocus Method. Though this is dependent on the actual tab order of your controls.

txt.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));

In reference to your comment, I did notice that and worked around it by making sure that I set the Listbox's selectedIndex to -1

lst.SelectedIndex = -1;
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top