#c# #winforms #events #combobox
#c# #winforms #Мероприятия #combobox
Вопрос:
Я создал пользовательский comboBox
интерфейс, который поддерживает изображения перед текстом элементов. Вот как это выглядит:
Для этого я создал новый вызываемый элемент управления ImageComboBox
, который хранится в dll
файле, на который ссылается мой проект winforms.
Это ImageComboBox
не что иное, как a ComboBox
с DrawMode
установленным значением DrawMode.OwnerDrawFixed
и удерживающим a ImageList
, который содержит все изображения для рисования. Существует a 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()) amp;amp;
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:
Найден ответ: код был неправильным, у меня было неправильное if
условие в начале фрагмента (но я все еще не понимаю, почему ошибка иногда происходила, а иногда нет).
Я должен использовать:
if (this.DroppedDown) {
// If the comboBox is dropped down
// Draw the blue rectangle
e.DrawBackground();
if (( e.State amp; 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
// ...