Элементы ListBox не отображаются в режиме OwnerDrawFixed - PullRequest
0 голосов
/ 22 февраля 2019

Пожалуйста, я действительно ценю, что любой может помочь мне решить следующую проблему.

У меня есть база данных Access, которую я хочу загрузить в ListBox .
Я установил ListBox DrawMode на OwnerDrawFixed, но когдаЯ запускаю приложение, которое показывает (System.Data.DataRowView) вместо всех записей базы данных.

Я должен сказать, что он работает нормально в нормальном DrawMode.

ListBox OwnerDrawFixe Mode Problem Image

Вот мой код:

private void Form1_Load(object sender, EventArgs e)
    {
        ListBox1.DataSource = GetData();
        ListBox1.DisplayMember = "empName";
    }

DataTable dt;

private DataTable GetData()
    {
        dt = new DataTable();
        using (OleDbConnection myConn = new OleDbConnection(ConfigurationManager.ConnectionStrings["database"].ConnectionString))
        {
            using (OleDbCommand myQuery = new OleDbCommand("select empName from empTable", myConn))
            {
                myConn.Open();
                OleDbDataReader myReader = myQuery.ExecuteReader();
                dt.Load(myReader);
            }
        }
        return dt;
    }


private void ListBox1_DrawItem(object sender, DrawItemEventArgs e)
    {
        e.DrawBackground();

        bool isItemSelected = ((e.State & DrawItemState.Selected) == DrawItemState.Selected);
        int itemIndex = e.Index;
        if (itemIndex >= 0 && itemIndex < ListBox1.Items.Count)
        {
            Graphics g = e.Graphics;

            SolidBrush backgroundColorBrush = new SolidBrush((isItemSelected) ? Color.FromArgb(255, 64, 64, 64) : Color.FromArgb(0,64,64,64)); 
            g.FillRectangle(backgroundColorBrush, e.Bounds);

            // Set text color
            string itemText = ListBox1.Items[itemIndex].ToString();

            SolidBrush itemTextColorBrush = (isItemSelected) ? new SolidBrush(Color.White) : new SolidBrush(Color.LightGray); 
            g.DrawString(itemText, e.Font, itemTextColorBrush, ListBox1.GetItemRectangle(itemIndex).Location);

            // Clean up
            backgroundColorBrush.Dispose();
            itemTextColorBrush.Dispose();
        }
        e.DrawFocusRectangle();
    }

Еще раз спасибо.

Ответы [ 2 ]

0 голосов
/ 22 февраля 2019

Так как ListBox равен с привязкой к данным , строки извлекаются из DataSource.

Так что вам нужно либо сделать это, когда вы хотите нарисовать владельца списка:

string itemText = ((DataRowView)listBox1.Items[itemIndex]).Row["empName"].ToString();

или, как предлагает Джими, использовать функцию GetItemText.

Обратите внимание, что это немного сложно найти, так как это не ListBox, а ListControl функция ..

Конечно, жесткое кодирование имени поля не очень хорошая идея, но это должно, по крайней мере, указать вам на данные.

0 голосов
/ 22 февраля 2019

Я предлагаю эти изменения в отношении способа загрузки данных и их использования для заполнения коллекции Items в ListBox и способа, которым метод DrawItems выполняет рисование элементов:

  1. Используйте OleDbDataAdapter для заполнения DataTable вместо OleDbDataReader.Он прост в использовании и заботится об открытии соединения для вас.
  2. Вернуть DataTable, затем использовать имя первого столбца в качестве ListBox DisplayMember, поэтому вам не нужно жестко задавать (здесь) имя поля, которое предоставляетИнформация для показа.Вы будете иметь эту ссылку только в одном месте (меньше подвержено ошибкам).
  3. Используйте DataTable.DefaultView .Объект DataView обеспечивает более прямой доступ к строкам и при необходимости может быть отфильтрован.ListBox нравится больше.
  4. Удалите ненужные части в методе DrawItem и используйте метод GetItemText () для получения строки, представляющей текст элемента ListControl.

Я всегда избавляюсь от DataTable.Если по каким-либо причинам вам нужна эта ссылка, не выбрасывайте ее, когда используете метод GetData()Form.Load здесь).В любом случае, похоже, что вы используете его просто для извлечения данных для заполнения ListBox.


private void Form1_Load(object sender, EventArgs e)
{
    using (DataTable dt = GetData()) {
        listBox1.DisplayMember = dt.Columns[0].ColumnName;
        listBox1.DataSource = dt.DefaultView;
    }
}

private DataTable GetData()
{
    using (OleDbConnection myConn = new OleDbConnection(ConfigurationManager.ConnectionStrings["database"].ConnectionString))
    using (OleDbCommand myQuery = new OleDbCommand("SELECT empName FROM empTable", myConn))
    using (OleDbDataAdapter adapter = new OleDbDataAdapter(myQuery)) {
        var dt = new DataTable();
        adapter.Fill(dt);
        return dt;
    }
}

private void ListBox1_DrawItem(object sender, DrawItemEventArgs e)
{
    if (e.Index < 0) return;
    e.DrawBackground();
    bool isItemSelected = ((e.State & DrawItemState.Selected) == DrawItemState.Selected);
    using (SolidBrush bgBrush = new SolidBrush(isItemSelected ? Color.FromArgb(64, 64, 64) : Color.FromArgb(0, 64, 64, 64)))
    using (SolidBrush itemBrush = isItemSelected ? new SolidBrush(Color.White) : new SolidBrush(Color.LightGray))
    {
        string itemText = listBox1.GetItemText(listBox1.Items[e.Index]);
        e.Graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
        e.Graphics.FillRectangle(bgBrush, e.Bounds);
        e.Graphics.DrawString(itemText, e.Font, itemBrush, e.Bounds);
    }
    e.DrawFocusRectangle();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...