Часть Editbox для ComboBox автоматически выбирается
У меня есть небольшая проблема, которая раздражает меня в течение нескольких часов.
В моем приложении WinForms (.NET 3.5) я создаю несколько ComboBoxes (DropDownStyle = DropDown) в TableLayoutPanel во время выполнения и заполняю его строками. ComboBoxes настроены на автоматическое изменение размера (Anchor = Left | Right).
Проблема заключается в том, что всякий раз, когда ComboBoxes изменяются в размерах (то есть диалоговом окне изменяется), часть editbox ComboBox получает выделение/выделение целиком. По-моему, это создает очень запутывающий эффект для клиента, которого я хочу избежать.
Проблема не возникает, если ComboBox имеет фиксированный размер.
Также обратите внимание, что изменение DropDownStyle не является вариантом - мне нужна возможность ввода текста вручную.
Я уже пытался испортить процесс переопределения метода OnPaint, который не совсем сработал.
Я также попытался очистить выбор в событии ComboBox.Resize, который работал в некотором роде, но выглядел как очень уродливое решение - было много мерцания, намеренно выбранный текст стал снят с выбора, и мне пришлось бы добавить обработчик событий к каждому и каждый ComboBox в моем диалоговом окне.
Есть ли лучшее решение этой проблемы?
Спасибо заранее.
С уважением,
Andy
Ответы
Ответ 1
Это старый вопрос, но я нашел, что он ищет ответ и в конечном итоге реализует свое собственное решение. Можете также разместить его здесь, правильно?
foreach (var cb in Controls.OfType<ComboBox>())
{
cb.Resize += (sender, e) => {
if (!cb.Focused)
cb.SelectionLength = 0;
};
}
намеренно выбранный текст снят с выбора
Эта ошибка WinForms не влияет на выбранные ComboBoxes, поэтому, игнорируя тех, у кого есть Focus, мы позаботимся о проблеме потери текущих выборов.
Мне нужно добавить обработчик событий для каждого ComboBox на моем диалоговое окно.
Взятый уход за петлей foreach. Поместите его в InitializeComponent() или ваш .ctor, если вы не хотите сломать конструктор, или попросите дизайнера сломать это.
было много мерцания
Я вижу только мерцание, если я изменяю размер очень быстро, но я нахожусь на Win7, чтобы он мог быть другим в XP.
Ответ 2
Ого. Спасибо, ребята!
По-видимому, эта ошибка сохранилась много лет.
Я создаю UserControl с .Net 4 (Visual Studio 2010).
Вот моя небольшая измененная версия кода bsneeze.
Приветствия
using System.Windows.Forms;
using System.Linq;
public MyUserControlCtor()
{
InitializeComponent();
foreach( Control ctrl in Controls)
{
ComboBox cb = ctrl as ComboBox;
if (cb != null)
{
cb.Resize += (sender, e) =>
{
if (!cb.Focused)
this.FCHZ_ComboBox.SelectionLength = 0;
};
}
}
}
Ответ 3
Ни один из ответов до сих пор не работал у меня. Единственный надежный метод, который я нашел, заключается в том, чтобы асинхронно публиковать сообщение через BeginInvoke
, который устанавливает SelectionLength
обратно в ноль после завершения всех остальных действий над элементом управления. Количество мерцаний очень раздражает и непрофессионально, но это лучшее, что я мог бы придумать... до сих пор.
internal class FixedComboBox : ComboBox
{
protected override void OnResize(EventArgs e)
{
if (IsHandleCreated && !Focused)
{
BeginInvoke((Action)(() =>
{
SelectionLength = 0;
}));
}
base.OnResize(e);
}
}
Ответ 4
Это, по-видимому, ошибка в собственной реализации Windows ComboBox
с DropDownStyle
of DropDown
.
Исправление, подробно описанное в других ответах здесь (установка свойства SelectionLength
в 0 (ноль) в событии ComboBox
Resize
), работает большую часть времени.
Однако я обнаружил, что даже это исправление для работы с этой ошибкой не всегда работает. Если ComboBox
находится в TableLayoutPanel
, а если TableLayoutPanel
имеет более одного столбца с типом Percent
размера, то это исправление часто не работает.
Картинка стоит тысячи слов. См. Следующий снимок экрана формы, которую я сделал, чтобы продемонстрировать проблему.
![введите описание изображения здесь]()
Ответ 5
Я обнаружил, что для длины выбора в поле со списком в событии с изменением размера, независимо от того, какой элемент управления находится в поле со списком, я обнаружил, что длина выбора лот меньше, чем это делается при изменении размера комбо.
Я действительно добился этого в VB.Net, но он должен применить то же самое к С#.
Ответ 6
Обработать событие Resize для родительского контейнера ComboBox. Поместите эту строку туда:
MyComboBox.SelectionLength = 0
Пример (VB, очевидно):
Private Sub MyControl_Resize(sender As Object, e As EventArgs) Handles Me.Resize
MyComboBox.SelectionLength = 0
End Sub
Удачи вам!
- BP
Ответ 7
Я работал, чтобы изменить selectionLength на 0, когда вызывается WM_WINDOWPOSCHANGED
.
Работает даже с параметром tableLayoutPanel, установленным на%.
protected override void WndProc(ref Message m) {
base.WndProc(ref m);
if(m.Msg == 0x0047) { // WM_WINDOWPOSCHANGED = 0x0047
if (SelectionLength != 0) {
SelectionLength = 0;
}
}
}