カスタムImageComboBoxが常に同じように動作するわけではない

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

このため、私はwinformsプロジェクトで参照されている dll に格納されている ImageComboBox という新しいコントロールを作成しました。 この ImageComboBox は、 DrawModeDrawMode.OwnerDrawFixed に設定されている ComboBox すべての画像を含む "http://msdn.microsoft.com/en-us/library/system.windows.forms.imagelist.aspx" rel = "nofollow noreferrer"> ImageList 描く。イメージを描画することを担当する DrawItemEventHandler があり、各アイテムのテキストがあります。

私は2ピクセルの問題に遭遇しますが、混乱する部分は、問題が常に発生するわけではないということです。新しいwinformsプロジェクトを作成して新しい ImageComboBox を追加するだけで問題はありません。 winformsプロジェクトに新しい ImageComboBox を追加すると、問題が発生します - 10回のうち9回(またはそのようなもの)。


私の2ピクセル問題を再現する手順は次のとおりです。

  1. フォームを開くとすべてがうまくいきます:
    最初のステップ
  2. imageComboBox をドロップダウンするとすべてがうまくいきます:
    第2ステップ
  3. アイテムを選択して項目を選択すると、すべてがうまくいきます:
    第3段階
  4. アイテムを選択するとすべてがうまくいきます:
    第4段階
  5. アイテムが選択されているときに imageComboBox をドロップすると、問題が発生します。選択したアイテムの前のイメージが右に2ピクセルシフトしてテキストが左に1ピクセル:
    第5歩 ズームしよう: 5番目のステップ - ズーム
  6. そして、ここで私はバグがないことを証明します:
    第5歩 - バグなし
    もう一度ズームしよう:
    第5歩 - バグはありません - ズームしました

私の ImageComboBoxDrawItemEvent があります:
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));
            }
        }
    }
}

私の見解では、コードは正しいはずですが、 if 条件が同じ結果を返さないことがあると思われるのに対し、

この問題が発生する可能性のある手掛かりはありますか?

1

1 答え

答えを見つけました:コードが正しくない、スニペットの最初に間違った 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

       //...
0
追加された