Часть окна редактирования ComboBox выбирается автоматически - PullRequest
13 голосов
/ 24 апреля 2009

У меня небольшая проблема, которая раздражала меня несколько часов.

В моем приложении WinForms (.NET 3.5) я создаю несколько ComboBox (DropDownStyle = DropDown) в TableLayoutPanel во время выполнения и заполняю его строками. ComboBox настроены на автоматическое изменение размера (Anchor = Left | Right).

Проблема заключается в том, что всякий раз, когда размеры ComboBox изменяются (то есть изменяется размер диалогового окна), часть поля редактирования поля ComboBox выделяется / выделяется полностью. По моему мнению, это создает очень запутанный эффект для клиента, которого я хочу избежать.

Проблема не появляется, если ComboBox имеет фиксированный размер.

Также обратите внимание, что изменение DropDownStyle не является опцией - мне нужна возможность вводить текст вручную.

Я уже пытался возиться с переопределением метода OnPaint, который не совсем работал. Я также попытался очистить выделение в событии ComboBox.Resize, которое работало в некотором роде, но казалось очень уродливым решением - было много мерцания, преднамеренно выделенный текст стал невыбранным, и мне нужно было бы добавить обработчик события к каждому и каждый ComboBox в моем диалоге.

Есть ли лучшее решение этой проблемы?

Заранее спасибо.

С уважением, Andy

Ответы [ 6 ]

13 голосов
/ 23 июня 2009

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

    foreach (var cb in Controls.OfType<ComboBox>())
    {
        cb.Resize += (sender, e) => {
            if (!cb.Focused)
                cb.SelectionLength = 0;
        };
    }

преднамеренно выделенный текст стал отмененным

Эта ошибка WinForms не влияет на выбранные комбинированные списки, поэтому, игнорируя те из них, в которых используется Focus, мы решаем проблему потери текущих выделений.

Я бы добавил обработчик событий каждому ComboBox на моем диалоговое окно.

Забота о петле foreach. Поместите его в InitializeComponent () или ваш .ctor, если вы не хотите нарушать конструктор, или попросите, чтобы дизайнер нарушил это.

было много мерцания

Я наблюдаю мерцание, только если меняю очень быстро, но на Win7, поэтому в XP оно может отличаться.

2 голосов
/ 30 марта 2012

Ничего себе. Спасибо, ребята!

Видимо, эта ошибка сохраняется много лет. Я создаю 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;
            };
        }
    } 
}
1 голос
/ 08 октября 2014

Ни один из ответов до сих пор не работал для меня. Единственный надежный метод, который я нашел, - это отправить сообщение асинхронно через BeginInvoke, которое устанавливает SelectionLength в ноль после завершения всех других действий в элементе управления. Количество мерцания очень раздражает и непрофессионально, но это лучшее, что я мог придумать ... пока.

internal class FixedComboBox : ComboBox
{
    protected override void OnResize(EventArgs e)
    {
        if (IsHandleCreated && !Focused)
        {
            BeginInvoke((Action)(() =>
                {
                    SelectionLength = 0;
                }));
        }
        base.OnResize(e);
    }
}
0 голосов
/ 22 ноября 2016

Похоже, что это ошибка в родной реализации Windows ComboBox с DropDownStyle из DropDown.

Исправление, подробно описанное в других ответах здесь (установка свойства SelectionLength на 0 (ноль) в событии ComboBox * Resize), работает в большинстве случаев.

Однако я обнаружил, что даже это исправление для обхода этой ошибки не всегда работает. Если ComboBox находится в TableLayoutPanel и если TableLayoutPanel имеет более одного столбца с Percent типом размера, то это исправление часто не работает.

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

enter image description here

0 голосов
/ 04 ноября 2014

Обработка события 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

0 голосов
/ 28 августа 2014

Я обнаружил, что установка длины выбора 0 для поля со списком в событии изменения размера любого элемента управления, в котором находится поле со списком, вызывает лот меньше мерцания вместо того, чтобы делать это при изменении размера комбинации сам по себе.

Я на самом деле достиг этого в VB.Net, но он должен применяться к C #.

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