WPF: выпадающий список Combobox выделяет текст - PullRequest
12 голосов
/ 18 сентября 2009

Когда я набираю в выпадающем списке, я автоматически открываю, активирует выпадающий список

searchComboBox.IsDropDownOpen = true;

Проблема здесь в том, что текст подсвечивается, а следующее нажатие клавиши перезаписывает предыдущий текст.

Как отключить подсветку текста при открытии ComboBox DropDown?

Ответы [ 5 ]

6 голосов
/ 22 августа 2013

У меня была та же самая проблема, и, как некоторые пользователи, которые были новичками в WPF, изо всех сил пытались заставить работать решение, данное Эйнаром Гудштейнссоном. Таким образом, в поддержку его ответа я вставляю здесь шаги, чтобы заставить это работать. (Или, точнее, как я это сделал).

Сначала создайте пользовательский класс combobox, который наследуется от класса Combobox. Смотрите код ниже для полной реализации. Вы можете изменить код в OnDropSelectionChanged в соответствии с вашими индивидуальными требованиями.

namespace MyCustomComboBoxApp { использование System.Windows.Controls;

public class MyCustomComboBox : ComboBox
{
    private int caretPosition;

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

        var element = GetTemplateChild("PART_EditableTextBox");
        if (element != null)
        {
            var textBox = (TextBox)element;
            textBox.SelectionChanged += OnDropSelectionChanged;
        }
    }

    private void OnDropSelectionChanged(object sender, System.Windows.RoutedEventArgs e)
    {
        TextBox txt = (TextBox)sender;

        if (base.IsDropDownOpen && txt.SelectionLength > 0)
        {
            txt.CaretIndex = caretPosition;
        }
        if (txt.SelectionLength == 0 && txt.CaretIndex != 0)
        {
            caretPosition = txt.CaretIndex;
        }
    }

}

Убедитесь, что этот пользовательский комбинированный класс существует в том же проекте. Тогда вы можете использовать приведенный ниже код для ссылки на этот комбо в вашем пользовательском интерфейсе.

<Window x:Class="MyCustomComboBoxApp.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:cc="clr-namespace:MyCustomComboBoxApp"
    Title="MainWindow" Height="350" Width="525" FocusManager.FocusedElement="{Binding ElementName=cb}">
<Grid>
    <StackPanel Orientation="Vertical">
        <cc:MyCustomComboBox x:Name="cb" IsEditable="True" Height="20" Margin="10" IsTextSearchEnabled="False" KeyUp="cb_KeyUp">
            <ComboBoxItem>Toyota</ComboBoxItem>
            <ComboBoxItem>Honda</ComboBoxItem>
            <ComboBoxItem>Suzuki</ComboBoxItem>
            <ComboBoxItem>Vauxhall</ComboBoxItem>
        </cc:MyCustomComboBox>
    </StackPanel>
</Grid>
</Window>

Вот и все! Любые вопросы, пожалуйста, задавайте! Я сделаю все возможное, чтобы помочь.

Спасибо Эйнару Гудштейнссону за его решение!

5 голосов
/ 18 марта 2011

Лучше поздно, чем никогда, и если кто-нибудь еще ударит по этой проблеме, он может использовать это.

Это невозможно сделать, если вы переопределите комбинированный список. Сначала получите дескриптор текстового поля, которое используется в шаблоне, и зарегистрируйтесь в выделенном событии.

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

  var element = GetTemplateChild("PART_EditableTextBox");
  if (element != null)
  {
    var textBox = (TextBox)element;
    textBox.SelectionChanged += OnDropSelectionChanged;
  }
}

private void OnDropSelectionChanged(object sender, RoutedEventArgs e)
{
    // Your code
}

Затем в обработчике событий вы можете снова установить выделение так, как вы хотите. В моем случае я вызывал IsDropDownOpen в коде. Сохраненный выбор там затем помещает это обратно в обработчик события. Уродливо, но сделал свое дело.

3 голосов
/ 21 августа 2014

Я думаю, что в Решении, предоставленном Эндрю Н, чего-то не хватает, так как, когда я пробовал это сделать, событие Selection Changed в TextBox помещало каретку не в то место. Поэтому я сделал это изменение, чтобы решить это.

namespace MyCustomComboBoxApp { using System.Windows.Controls;

public class MyCustomComboBox : ComboBox
{
    private int caretPosition;

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

        var element = GetTemplateChild("PART_EditableTextBox");
        if (element != null)
        {
            var textBox = (TextBox)element;
            textBox.SelectionChanged += OnDropSelectionChanged;
        }
    }

    private void OnDropSelectionChanged(object sender, System.Windows.RoutedEventArgs e)
    {
        TextBox txt = (TextBox)sender;

        if (base.IsDropDownOpen && txt.SelectionLength > 0)
        {
            caretPosition = txt.SelectionLength; // caretPosition must be set to TextBox's SelectionLength
            txt.CaretIndex = caretPosition;
        }
        if (txt.SelectionLength == 0 && txt.CaretIndex != 0)
        {
            caretPosition = txt.CaretIndex;
        }
    }
}
2 голосов
/ 18 октября 2016

В дополнение к ответу clsturgeon я решил проблему, установив выбор при наступлении события DropDownOpened:

private void ItemCBox_DropDownOpened(object sender, EventArgs e)
{
    TextBox textBox = (TextBox)((ComboBox)sender).Template.FindName("PART_EditableTextBox", (ComboBox)sender);
    textBox.SelectionStart = ((ComboBox)sender).Text.Length;
    textBox.SelectionLength = 0;
}
0 голосов
/ 18 сентября 2009

Когда комбокс получит фокус, вы можете отключить подсветку текста (то есть, не выделяя текст в событии GotFocus). Однако, когда вы выпадаете из выпадающего списка, система собирается найти элемент в списке и сделать его выбранным. Это в свою очередь автоматически выделяет текст. Если я понимаю поведение, которое вы ищете, я не верю, что это вполне возможно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...