WPF: раскрытие списка сочетаний подчеркивает текст
Когда я печатаю в поле со списком, я автоматически открывает раскрывающийся список
searchComboBox.IsDropDownOpen = true;
Здесь проблема: текст выделяется, а следующий ключ переписывает предыдущий текст.
Как отключить выделение текста, когда открывается ComboBox DropDown?
Ответы
Ответ 1
Лучше поздно, чем никогда, и если кто-то другой ударит по этой проблеме, он может это использовать.
Если вы переопределяете combobox, это нужно сделать.
Сначала возьмите дескриптор текстового поля, который используется в шаблоне, и зарегистрируйтесь для выделения события.
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 в коде. Сохраненный выбор, затем верните его в обработчик событий. Уродливо, но сделал трюк.
Ответ 2
У меня была такая же проблема, и, как некоторые из пользователей, являющихся новыми для WPF, изо всех сил пытались найти решение, данное Эйнаром Густштинссоном для работы. Поэтому в поддержку его ответа я прикладываю здесь шаги, чтобы заставить это работать. (Или более точно, как я получил это, чтобы работать).
Сначала создайте собственный класс combobox, который наследуется от класса Combobox. См. Код ниже для полной реализации. Вы можете изменить код в OnDropSelectionChanged в соответствии с вашими индивидуальными требованиями.
пространство имен 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;
}
}
}
Убедитесь, что этот пользовательский класс комбо существует в одном проекте. THEN вы можете использовать приведенный ниже код, чтобы ссылаться на эту комбо в пользовательском интерфейсе.
<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>
Вот оно! Любые вопросы, пожалуйста, спросите! Я сделаю все возможное, чтобы помочь.
Чрезвычайно важно для Эйнара Густштинсона за его решение!
Ответ 3
Я думаю, что в решении, предоставленном Эндрю N, есть что-то не так, как когда я это пробовал, событие 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 SelectionLength
txt.CaretIndex = caretPosition;
}
if (txt.SelectionLength == 0 && txt.CaretIndex != 0)
{
caretPosition = txt.CaretIndex;
}
}
}
Ответ 4
В дополнение к ответу 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;
}
Ответ 5
Когда comboxbox получает фокус, вы можете отключить выделение текста (т.е. не выделяя текст при событии GotFocus). Однако, когда вы выпадаете на поле со списком, система собирается найти элемент в списке и сделать выбранный элемент. Это, в свою очередь, автоматически выделяет текст. Если я понимаю поведение, которое вы ищете, я не считаю, что это возможно.