views:

516

answers:

4

Hi,

I am trying to make a TextBox behavior for an on-screen keyboard, it can update the text in the textbox but I can't get it to focus the textbox and move the caret to the end of the text once it's done updating.

I have tried using TextBox.Focus() and TextBox.Select() in both orders with no luck.

Thanks for your time

+2  A: 

Changing the focus from within an input event handler (i.e. mouse click on a virtual key) will fail, since the mouse-up event (or key-up) will return the focus to the original element. In order to make it work, you have to dispatch the focus command to a later time using the Dispatcher object.

Example:

Dispatcher.Invoke(new Action(() =>
{
    textBox1.Focus();
    textBox1.SelectionStart = textBox1.Text.Length;
    // or textBox1.Select(textBox1.Text.Length,0);
}), System.Windows.Threading.DispatcherPriority.Background);
Aviad P.
Ah, that makes sense. I'll look into that thenThank you very much
JimmySavile
BTW, this applies to WPF, I haven't tested it on Silverlight, so let me know if there's any problems with it, even if I can't answer, I'd be interested in knowing about them.
Aviad P.
Not sure if I am meant to do everything in comments or add a new response below so I've done that..
JimmySavile
A: 

Here is a simple example of moving the cursor to the end of a TextBox once you have updated it.

TextBox.Focus();
TextBox.Text = "sometext ";
TextBox.SelectionStart = TextBox.Text.Length;
Jeff Beck
A: 

I've tried the following basic code and it still doesn't even set the focus on the text box, the FocusAction method does get called though:

    private delegate void FocusDelegate();

    private void FocusAction()
    {
        Target.Focus();
    }

    public void KeyPressed(KeystrokeInformation keystrokeInformation)
    {
        Target.Text += keystrokeInformation.Key;

        Dispatcher.BeginInvoke(new FocusDelegate(FocusAction));
    }
JimmySavile
Did you try it exactly as I specified? I used `Invoke` not `BeginInvoke`, and I specified a priority for execution `DispatcherPriority.Background`.
Aviad P.
Don't think it's supported in Silverlight, only has the option for BeginInvoke..
JimmySavile
What about the priority argument?
Aviad P.
Nope there isn't that option either
JimmySavile
So you have a button then on the click of the button you call KeyPressed or when exactly are you calling this function?
Jeff Beck
A: 

I had a similar situation and I attached a "TextChanged" Handler to my textbox as shown here.

<TextBox Name="tbTextEntry" Width="200" HorizontalAlignment="Center" Background="Plum" Text="{Binding Entered_text,Mode=TwoWay}" TextChanged="OnTextChanged_Handler"></TextBox>

And handled the event like this(thanks Jeff Beck from comment above):

protected void OnTextChanged_Handler(object sender, RoutedEventArgs e)
{
    TextBox my_text_box = (TextBox)sender;
    my_text_box.SelectionStart = my_text_box.Text.Length;
    Debug.WriteLine("OnTextChanged_Handler called !");
    return;
}

This is inefficient for the cases when a person leaves the onscreen keyboard and start to use the real keyboard because each new character will then cause this handler to be invoked needlessly as the cursor works just fine with real keyboard. Any more efficient solution welcome !

Hope that helps. Thanks.

shadowman