9

I am using an editable ComboBox in wpf but when i try to set focus from C# code, it is only shows selection. but i want to go for edit option (cursor should display for user input).

Raj
  • 3,890
  • 7
  • 52
  • 80

4 Answers4

12

You can try this code:

        var textBox = (comboBox.Template.FindName("PART_EditableTextBox", comboBox) as TextBox);
        if (textBox != null)
        {
            textBox.Focus();
            textBox.SelectionStart = textBox.Text.Length;
        }
Rikker Serg
  • 325
  • 1
  • 11
  • 3
    @RAJK That code worked perfectly for me. It properly solves the problem of needing focus on an editable combobox when a window is first displayed. What's not stated clearly is that you must put the code in the Loaded event of the window containing the editable combobox. – Ken Beckett Oct 24 '11 at 19:00
  • Perfect! Solved me lots and lots of problems! Thank you so much! – Junior Silva Dec 24 '17 at 14:21
6

Based on the answer of user128300 above I came up with a slightly simpler solution. In the constructor or ContextChangedHandler the code is waiting for the control to be loaded before putting the focus on the UI element

myComboBox.GotFocus += MyComboBoxGotFocus;
myComboBox.Loaded += (o, args) => { myComboBox.Focus(); };

Then in the focus even handler I select all the text from the start to the end

private void MyComboBoxGotFocus(object sender, RoutedEventArgs e)
{
    var textBox = myComboBox.Template.FindName("PART_EditableTextBox", myComboBox) as TextBox;
    if (textBox != null)
        textBox.Select(0, textBox.Text.Length);
}

In xaml the combobox is editable. By selecting all the text when user type a key it is resetting the previous value

<ComboBox x:Name="myComboBox" IsEditable="True" />
Claude Ducharme
  • 301
  • 3
  • 3
  • Template is null in my case... Maybe because it's .Net 6? – hardfork May 27 '22 at 14:25
  • Oh, I have had it in a behavior... As Ken Beckett said: "What's not stated clearly is that you must put the code in the Loaded event of the window containing the editable combobox. " – hardfork May 27 '22 at 14:36
3

You might try deriving from ComboBox and access the internal TextBox, like this:

public class MyComboBox : ComboBox
{
    TextBox _textBox;

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        _textBox = Template.FindName("PART_EditableTextBox", this) as TextBox;
        if (_textBox != null)
        {
            _textBox.GotKeyboardFocus += _textBox_GotFocus;
            this.Unloaded += MyComboBox_Unloaded;
        }
    }

    void MyComboBox_Unloaded(object sender, System.Windows.RoutedEventArgs e)
    {
        _textBox.GotKeyboardFocus -= _textBox_GotFocus;
        this.Unloaded -= MyComboBox_Unloaded;
    }

    void _textBox_GotFocus(object sender, System.Windows.RoutedEventArgs e)
    {
        _textBox.Select(_textBox.Text.Length, 0); // set caret to end of text
    }

}

In your code you would use it like this:

<Window x:Class="EditableCbox.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:EditableCbox"
    Title="Window1" Height="300" Width="300">
    ...
        <local:MyComboBox x:Name="myComboBox" IsEditable="True" Grid.Row="0" Margin="4">
            <ComboBoxItem>Alpha</ComboBoxItem>
            <ComboBoxItem>Beta</ComboBoxItem>
            <ComboBoxItem>Gamma</ComboBoxItem>
        </local:MyComboBox>
    ...
</Window>

This solution slightly dangerous, however, because in upcoming versions of WPF, Microsoft might decide also to add a GotKeyboardFocus event handler (or similar event handlers), which might get in conflict in with the event handler in MyComboBox.

0

Based on Rikker Serg's answer, you can use that code in your constructor (after InitializeComponent) and dispatch it instead of needing to create custom controls or event handlers.

public NewMessageWindow()
{
    InitializeComponent();

    Dispatcher.BeginInvoke(new Action(() =>
    {
        var textBox = myComboBox.Template.FindName("PART_EditableTextBox", cbUsers) as TextBox;
        if (textBox != null)
        {
            textBox.Focus();
            textBox.SelectionStart = textBox.Text.Length;
        }
    }));

}