0

我正在尝试用两个自定义列和一些从数据表中填充的行来填充无界的 datagridview。第一个 datagridview 的列必须从第一个数据表列填充,依此类推。第一列是品牌名称,第二列是品牌图片。

我使用这段代码和一些 linq 来准备两个数组

DataTable dt = new DataTable();
dt = clsTransmit.FillDataTable("SELECT brandName, brandPic FROM brands", false);

int count = dt.Rows.Count;
string[] names = dt.AsEnumerable().Select(row => row.Field<string>("brandName")).ToArray();
string[] pics = dt.AsEnumerable().Select(row => row.Field<string>("brandPic")).ToArray();

现在我想填写我已经尝试过这些代码的datagridview:

DataGridViewColumn brandName = new DataGridViewColumn();
DataGridViewImageColumn imageCol = new DataGridViewImageColumn();
dgv.Columns.Add(brandName);
dgv.Columns.Add(imageCol);
dgv.Columns[0].HeaderText = "Brand Name";
dgv.Columns[1].HeaderText = "Brand Picture";

DataGridViewRow n = new DataGridViewRow();
DataGridViewRow p = new DataGridViewRow();

for (int i = 0; i < count-1; i++)
{
    n.Cells[i].Value = names[i];
    p.Cells[i].Value = imgList.Images[i];
}

dgv.Rows.AddRange(n);
dgv.Rows.AddRange(p);

我也试试这个:

dgv.Rows.Add(names);
dgv.Rows.Add(pics);

运行后显示错误消息:

指数超出范围。


好的,更新我的代码并得到答案我使用图像列表并通过以下方式填充它:

foreach (var item in pics)
  {
       Image img = Image.FromFile(item);
       imgList.Images.Add(img);
  }

并使用这些代码填充gridview并得到正确答案:

dgv.Columns.Add("brandName", "Brand Name");

for (int i = 0; i < count; i++)
{
      dgv.Rows.Add(new object[] {names[i]});
}

DataGridViewImageColumn imageCol = new DataGridViewImageColumn();
dgv.Columns.Add(imageCol);
dgv.Columns[1].HeaderText = "Brand Logo";
dgv.Rows.Add();
for (int i = 0; i < count; i++)
{
      dgv.Rows[i].Cells[1].Value = imgList.Images[i];
}

但我现在有另一个问题,问题是 datagridview 在所有行的底部都有额外的空行。我已经取消选中启用添加、编辑、删除 datagridview 但它仍然有一个额外的行:(

4

2 回答 2

1

如果你想在 中显示你的图像DataGridViewImageColumn,你必须像这样设置你的数据:

dt.Columns.Add("Picture", typeof(byte[]));
var actualData = dt.AsEnumerable()
                   .Select(row=> {
                       row.SetField<byte[]>("Picture", GetBytesFromImagePath(row.Field<string>("brandPic"));
                       return row;
                    }).CopyToDataTable();
actualData.Columns.Remove("brandPic");
dgv.DataSource = actualData;

//Use this method to get byte[] data from the image path
private byte[] GetBytesFromImagePath(string imagePath){
   using(MemoryStream ms = new MemoryStream()){
     Image img = Image.FromFile(imagePath);
     img.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
     return ms.GetBuffer();
   }
}
//Set-up Header Text
dgv.Columns[0].HeaderText = "Brand Name";
dgv.Columns[1].HeaderText = "Brand Picture";

注意:您不需要dgv手动添加列,只需DataSource在我的代码中设置。

如果您保存URL到图像而不是local filepath,您可以像这样修改代码:

dt.Columns.Add("Picture", typeof(byte[]));
System.Net.WebClient client = new System.Net.WebClient();
int i = 0;
client.DownloadDataAsync(new Uri(dt.Rows[0].Field<string>("brandPic")), dt.Rows[0]);
client.DownloadDataCompleted += (se, e) => {
   ((DataRow)e.UserState).SetField<byte[]>("Picture", e.Result);
   if(++i == dt.Rows.Count) return;               
   client.DownloadDataAsync(new Uri(dt.Rows[i].Field<string>("brandPic")), dt.Rows[i]);
};            
dt.Columns.Remove("brandPic");
dgv.DataSource = dt;
于 2013-10-23T19:20:05.793 回答
0

感谢国王国王的帮助我找到了答案

DataTable dt = new DataTable();
dt = clsTransmit.FillDataTable("SELECT brandName, brandPic FROM brands", false);

int count = dt.Rows.Count;
string[] names = dt.AsEnumerable().Select(row => row.Field<string>("brandName")).ToArray();
string[] pics = dt.AsEnumerable().Select(row => row.Field<string>("brandPic")).ToArray();

foreach (var item in pics)
{
   Image img = Image.FromFile(item);
   imgList.Images.Add(img);
}

dgv.Columns.Add("brandName", "Brand Name");

for (int i = 0; i < count; i++)
{
   dgv.Rows.Add(new object[] {names[i]});
}

DataGridViewImageColumn imageCol = new DataGridViewImageColumn();
dgv.Columns.Add(imageCol);
dgv.Columns[1].HeaderText = "Brand Logo";
dgv.Rows.Add();
for (int i = 0; i < count; i++)
{
   dgv.Rows[i].Cells[1].Value = imgList.Images[i];
}
dgv.Rows.RemoveAt(count);
于 2013-10-23T20:47:04.367 回答