ListBox项目不在OwnerDrawFixed模式下显示 [英] ListBox items do not show in OwnerDrawFixed Mode

查看:171
本文介绍了ListBox项目不在OwnerDrawFixed模式下显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请,我真的很感谢任何人都可以帮助我解决以下问题.

Please, I really appreciate that anyone can help me with the following problem.

我有一个Access数据库,我想将其加载到 ListBox 中.
我将ListBox DrawMode设置为 OwnerDrawFixed ,但是当我运行该应用程序时,它显示的是(System.Data.DataRowView)而不是所有的数据库记录.

I have an Access database which I want to load it into the ListBox.
I set the ListBox DrawMode to OwnerDrawFixed, but when I run the application it shows (System.Data.DataRowView) instead of all the database records.

我必须说,它在Normal DrawMode下工作正常.

I must say that it works fine in Normal DrawMode.

这是我的代码:

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();
    }

再次感谢您.

推荐答案

我建议这些更改与数据加载和用于填充ListBox的Items集合的方式以及DrawItems方法执行以下操作的方式有关物品的涂漆:

I suggest these changes in relation to the way the data is loaded and used to fill the Items collection of a ListBox and the way the DrawItems method performs the painting of the items:

  1. 使用 GetItemText()方法来检索表示ListControl项目文本的字符串. /li>
  1. Use a OleDbDataAdapter to fill the DataTable instead of a OleDbDataReader. It's simple to use and it takes care of opening the connection for you.
  2. Return a DataTable, then use the first Column's name as the ListBox DisplayMember, so you don't need to hardcode (here) the name of the Field that provides the information to show. You'll have this reference in one place only (less error prone).
  3. Remove the unnecessary parts in the DrawItem method and make use of the GetItemText() method to retrieve the string that represents the ListControl item text.

我一直在处理DataTable.如果出于任何原因需要此参考,请在使用GetData()方法(此处为Form.Load)时不要处理该参考.无论如何,看起来您只是在使用它来检索数据以填充ListBox.

I'm always disposing of the DataTable. If, for any reasons, you need this reference, don't dispose of it when you use the GetData() method (in Form.Load, here). Anyway, it looks like you're using it just to retrieve the data to fill the ListBox.

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

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;
    var lbx = sender as ListBox;
    bool isItemSelected = ((e.State & DrawItemState.Selected) == DrawItemState.Selected);
    using (SolidBrush bgBrush = new SolidBrush(isItemSelected ? Color.FromArgb(64, 64, 64) : lbx.BackColor))
    using (SolidBrush itemBrush = isItemSelected ? new SolidBrush(lbx.ForeColor) : new SolidBrush(Color.LightGray)) {
        string itemText = lbx.GetItemText(lbx.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();
}

这篇关于ListBox项目不在OwnerDrawFixed模式下显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆