开发者

How to add a focus to an editable ComboBox in WPF

开发者 https://www.devze.com 2023-01-02 06:52 出处:网络
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 开发者_Python百科go for edit option (cursor should display for user input).Yo

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 开发者_Python百科go for edit option (cursor should display for user input).


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;
        }


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" />


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.


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;
        }
    }));

}
0

精彩评论

暂无评论...
验证码 换一张
取 消