Я создал пользовательский comboBox
, который поддерживает изображения перед текстом элементов.Вот как это выглядит:
Для этого я создал новый элемент управления ImageComboBox
, который хранится в dll
, указанном в моем проекте winforms.
Этот ImageComboBox
ничего болеечем ComboBox
с DrawMode
, установленным на DrawMode.OwnerDrawFixed
и удерживающим ImageList
, который содержит все изображения для рисования.Существует DrawItemEventHandler
, который отвечает за рисование изображения и текста каждого элемента.
Я сталкиваюсь с проблемой двух пикселей, но сбивает с толку то, что проблема не всегда возникает.Когда я создаю новый проект winforms и просто добавляю новый ImageComboBox
, у меня нет проблемы.Когда я добавляю новый ImageComboBox
в проект winforms довольно продвинутый, возникает проблема - 9 раз из 10 (или что-то в этом роде).
Вот шаг для воспроизведения моего двухпиксельногопроблема:
- Когда я открываю форму, все в порядке:
- Когда я опускаю
imageComboBox
, все в порядке:
- При наведении курсора на элемент для выбора все нормально:
- Когда я выбираю элемент, все нормально:
- И когда я опускаю
imageComboBox
, когда выбран элемент, возникает проблема: изображение перед выбранным элементом смещается на два пикселя справа, а текст смещается на один пиксель слева:
Давайте увеличим масштаб: - И вот доказательство, у меня иногда нет ошибки:
Давайте снова увеличим масштаб:
Вот 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
не возвращают одинаковые результаты, в то время как я думаю, что так и должно быть.
Есть какие-либо подсказки, откуда может возникнуть эта проблема?