Пользовательский ImageComboBox не всегда ведет себя одинаково - PullRequest
1 голос
/ 28 октября 2011

Я создал пользовательский comboBox, который поддерживает изображения перед текстом элементов.Вот как это выглядит: ImageComboBox

Для этого я создал новый элемент управления ImageComboBox, который хранится в dll, указанном в моем проекте winforms.
Этот ImageComboBox ничего болеечем ComboBox с DrawMode, установленным на DrawMode.OwnerDrawFixed и удерживающим ImageList, который содержит все изображения для рисования.Существует DrawItemEventHandler, который отвечает за рисование изображения и текста каждого элемента.

Я сталкиваюсь с проблемой двух пикселей, но сбивает с толку то, что проблема не всегда возникает.Когда я создаю новый проект winforms и просто добавляю новый ImageComboBox, у меня нет проблемы.Когда я добавляю новый ImageComboBox в проект winforms довольно продвинутый, возникает проблема - 9 раз из 10 (или что-то в этом роде).


Вот шаг для воспроизведения моего двухпиксельногопроблема:

  1. Когда я открываю форму, все в порядке:
    First step
  2. Когда я опускаю imageComboBox, все в порядке:
    Second step
  3. При наведении курсора на элемент для выбора все нормально:
    Third step
  4. Когда я выбираю элемент, все нормально:
    Fourth step
  5. И когда я опускаю imageComboBox, когда выбран элемент, возникает проблема: изображение перед выбранным элементом смещается на два пикселя справа, а текст смещается на один пиксель слева:
    Fifth step
    Давайте увеличим масштаб: Fifth step - zoomed
  6. И вот доказательство, у меня иногда нет ошибки:
    Fifth step - no bug
    Давайте снова увеличим масштаб:
    Fifth step - no bug - zoomed

Вот DrawItemEvent моего ImageComboBox:
(this._imageList - мой ImageList объект)

private void OnDrawItem(object sender, DrawItemEventArgs e) {
    if (e.Index >= 0) {
        // If the current item is one in the comboBox

        // Compute the X location of the text to drawn
        int strLocationX = this._imageList.Images.Count > e.Index ?
                this._imageList.Images[e.Index].Width + 1 :
                e.Bounds.X + 1;

        // Get the displayed text of the current item
        String itemText = this.Items[e.Index].ToString();

        if (this.DroppedDown) {
            // If the comboBox is dropped down

            // Draw the blue rectangle
            e.DrawBackground();

            if (e.State == DrawItemState.ComboBoxEdit) {
                // If we are drawing the selected item

                // Draw the text
                e.Graphics.DrawString(itemText, this.Font, Brushes.Black, 
                    new Point(strLocationX + 1, e.Bounds.Y + 1));

                if (this._imageList.Images.Count > e.Index) {
                    // If we have an image available

                    // Draw the image
                    e.Graphics.DrawImage(this._imageList.Images[e.Index],
                        new Point(e.Bounds.X, e.Bounds.Y - 1));
                }

            } else {
                // If we are drawing one of the item in the drop down

                // Check if the item is being highlighted
                if (e.State.ToString().Contains(DrawItemState.Focus.ToString()) &&
                    e.State.ToString().Contains(DrawItemState.Selected.ToString())) {
                    // Draw the text in White
                    e.Graphics.DrawString(itemText, this.Font, Brushes.White, 
                        new Point(strLocationX, e.Bounds.Y + 1));
                } else {
                    // Draw the text in Black
                    e.Graphics.DrawString(itemText, this.Font, Brushes.Black, 
                        new Point(strLocationX, e.Bounds.Y + 1));
                }

                if (this._imageList.Images.Count > e.Index) {
                    // If we have an image available

                    // Draw the image
                    e.Graphics.DrawImage(this._imageList.Images[e.Index],
                        new Point(e.Bounds.X + 2, e.Bounds.Y - 1));
                }
            }
        } else {
            // If the comboBox is not dropped down

            // Draw the text
            e.Graphics.DrawString(itemText, this.Font, Brushes.Black, 
                new Point(strLocationX + 1, e.Bounds.Y + 1));

            if (this._imageList.Images.Count > e.Index) {
                // If we have an image available

                // Draw the image
                e.Graphics.DrawImage(this._imageList.Images[e.Index],
                    new Point(e.Bounds.X, e.Bounds.Y - 1));
            }
        }
    }
}

Для моегоPOINС точки зрения, код должен быть правильным, но кажется, что иногда условия if не возвращают одинаковые результаты, в то время как я думаю, что так и должно быть.

Есть какие-либо подсказки, откуда может возникнуть эта проблема?

1 Ответ

0 голосов
/ 28 октября 2011

Нашел ответ: код был неправильным, у меня было неверное условие if в начале фрагмента (но я до сих пор не понимаю, почему ошибка иногда происходила, а иногда нет).

Я должен использовать:

if (this.DroppedDown) {
    // If the comboBox is dropped down

    // Draw the blue rectangle
    e.DrawBackground();

    if (( e.State & DrawItemState.ComboBoxEdit ) == DrawItemState.ComboBoxEdit) {
        // If we are drawing the selected item

        // ...

вместо:

if (this.DroppedDown) {
    // If the comboBox is dropped down

    // Draw the blue rectangle
    e.DrawBackground();

    if (e.State == DrawItemState.ComboBoxEdit) {
        // If we are drawing the selected item

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