如何从DataGridViewRow填充DataGridView

时间:2013-10-23 18:58:52

标签: c# winforms 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但仍然有一个额外的行:(

2 个答案:

答案 0 :(得分: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;

答案 1 :(得分: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);