c# - ListBox 项目在 OwnerDrawFixed 模式下不显示

标签 c# .net winforms ms-access graphics

拜托,我真的很感激任何人都可以帮助我解决以下问题。

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

我必须说它在 Normal 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();
    }

再次感谢。

最佳答案

我建议这些更改与加载数据和用于填充 ListBox 的 Items 集合的方式以及 DrawItems 方法执行项目绘制的方式有关:

  1. 使用 OleDbDataAdapter填充 DataTable 而不是 OleDbDataReader。它使用简单,并负责为您打开连接。
  2. 返回一个DataTable,然后使用第一个Column的名字作为ListBox DisplayMember,所以你不需要硬编码(这里)提供要显示的信息的字段的名称。您将只在一个地方有此引用(不易出错)。
  3. 删除DrawItem 方法中不需要的部分并使用GetItemText()方法检索表示 ListControl 项文本的字符串。

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    var dt = GetData();
    if (dt != null) {
        listBox1.DisplayMember = dt.Columns[0].ColumnName;
        listBox1.DataSource = dt;
    }
}

private DataTable GetData()
{
    using (var conn = new OleDbConnection(ConfigurationManager.ConnectionStrings["database"].ConnectionString))
    using (var cmd = new OleDbCommand("SELECT empName FROM empTable", conn)) {
        conn.Open();
        using (var reader = cmd.ExecuteReader()) {
            if (!reader.HasRows) return null;
            var dt = new DataTable();
            dt.Load(reader);
            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 (var bgBrush = new SolidBrush(isItemSelected ? Color.FromArgb(64, 64, 64) : lbx.BackColor))
    using (var 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();
}

关于c# - ListBox 项目在 OwnerDrawFixed 模式下不显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54831018/

相关文章:

c# - 无法在 sting c# 中编写脚本

.net - 在.net中,知道周号如何获取工作日日期?

c# - Windows 服务 OnStop 等待完成处理

c# - 如何使 IEnumerable<T> 只读?

c# - 我如何添加一个新的进度条来显示整体下载?

c# - 在 wpf 或 winform 中使用数据网格(或数据 GridView )时遇到问题

c# - 多种形式的全局化

c# - 使用多种形式

c# - 如何使用 C# 获取正在运行的应用程序的开始菜单名称?

c# - 处理网页浏览器控件的点击事件