Пожалуйста, я очень ценю, что кто-нибудь может помочь мне со следующей проблемой.
У меня есть база данных Access, которую я хочу загрузить в СписокБокс.
Я установил для ListBox DrawMode значение OwnerDrawFixed, но когда я запускаю приложение, оно показывает (System.Data.DataRowView) вместо всех записей базы данных.
Должен сказать, что он отлично работает в режиме 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();
}
Еще раз спасибо.
@TaW, спасибо. Я очень много работал над этим. но так и не смог разобраться. пожалуйста, помогите мне немного с кодом.





Я предлагаю эти изменения в отношении того, как данные загружаются и используются для заполнения коллекции Items ListBox, а также в том, как метод DrawItems выполняет отрисовку элементов:
DataTable вместо OleDbDataReader. Он прост в использовании, и он позаботится об открытии соединения для вас.DataTable, затем используйте имя первого столбца как ListBox DisplayMember, поэтому вам не нужно жестко кодировать (здесь) имя поля, которое предоставляет информацию для отображения. У вас будет эта ссылка только в одном месте (менее подвержено ошибкам).DrawItem и используйте метод ПолучитьТекстЭлемента() для получения строки, представляющей текст элемента 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 (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 равен с привязкой к данным, строки извлекаются из DataSource.
Поэтому вам нужно либо сделать это, когда вы хотите нарисовать список владельца:
string itemText = ((DataRowView)listBox1.Items[itemIndex]).Row["empName"].ToString();
или, как предлагает Джими, используйте функцию GetItemText.
Обратите внимание, что это немного сложно найти, поскольку это не функция ListBox, а функция ListControl.
Конечно, жесткое кодирование имени поля — не очень хорошая идея, но это должно, по крайней мере, указать вам на данные.
Обычно это симптом добавления не строки, а некоторого объекта (класса без хорошего метода ToString) в список. Разве вы не должны также установить ValueMember?