Прыстасаваныя ImageComboBox не заўсёды паводзіць сябе так жа, як

I have created a custom comboBox that supports images in front of the items text. Here's how it looks: ImageComboBox

Для гэтага я стварыў новы элемент кіравання пад назвай ImageComboBox , які захоўваецца ў длл спасылка ў маім праекце WinForms.
Гэта ImageComboBox гэта не больш чым ComboBox з DrawMode усталяваны ў становішча DrawMode.OwnerDrawFixed і ўтрымліваючы ImageList , які змяшчае ўсе выявы маляваць. Існуе а DrawItemEventHandler , які адказвае за маляванне малюнка і тэкст кожнага элемента.

Я сутыкаюся з праблемай на два пікселя, але заблытаная частка з'яўляецца тое, што гэтая праблема не заўсёды адбываецца. Калі я ствараю новы праект WinForms і проста дадаць новы ImageComboBox , у мяне няма праблемы. Калі я дадаць новы ImageComboBox на праекце WinForms даволі прасунуты, праблема ўзнікае - у 9 раз з 10 раз (ці нешта падобнае).


Вось крок, каб прайграць маю праблему два піксела:

  1. When I open the form, everything's fine:
    First step
  2. When I drop down the imageComboBox, everything's fine:
    Second step
  3. When I hover an item to select it, everything's fine:
    Third step
  4. When I select an item, everything's fine:
    Fourth step
  5. And when I drop down the imageComboBox when there is an item selected, the problem occurs: the image in front of the selected item is shifted by two pixels on the right and the text is shifted by one pixel on the left:
    Fifth step
    Let's zoom: Fifth step - zoomed
  6. And here the proof I don't have the bug sometimes:
    Fifth step - no bug
    Let's zoom again:
    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));
            }
        }
    }
}

З майго пункту гледжання, код павінен быць правільным, але мне здаецца, што часам , калі ўмова не вяртае тыя ж вынікі, у той час як я думаю, што ён павінен рабіць.

Любы ключ пра тое, дзе гэтая праблема можа зыходзіць ад?

1

1 адказы

Знойдзены адказ: код ня меў рацыю, у мяне быў няправільны , калі стан у пачатку фрагмента кода (але я да гэтага часу не разумею, чаму памылка адбываецца часам, а часам і няма).

Я павінен выкарыстоўваць:

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

       //...
0
дададзена