2013-10-23 110 views
0

我試圖用兩個自定義列和一些從數據表填充的行填充無界的datagridview。 第一個datagridview的列必須從第一個數據表列填充,等等。 第一欄是品牌的名稱,第二是品牌的圖片。如何從DataGridViewRow填充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在所有r的底部有多餘的空行ows。我已經取消勾選啓用添加,編輯,刪除的datagridview但它仍然有一個額外的行:(

+0

我的代碼是不是這樣複雜。正如我所說的,你不應該手動添加列到你的'DataGridView',而是使用'DataSource'。我發佈的代碼只有一點'IO',一點''LINQ',以及'DataGridView'的一點用法,你應該嘗試一下並逐漸理解它。 –

+0

那麼你的更新代碼有什麼問題? –

+0

刪除行'dgv.Rows.Add();' –

回答

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; 
+0

@ user1592474不要感謝太快,你只需要嘗試代碼並給出一些反饋,以便我可以改進答案。我很確定它的工作原理。順便說一句,你的代碼有很多錯誤,你使用'DataGridViewImageColumn',但你的'brandPic'似乎是'string'指的是圖像文件路徑或URL,你在'Row index'中傳入'.Cells [...]'這需要一些'Column index'使你的'IndexOutOfRangeException',...無論如何,你的代碼太混亂了,解決方案是使用全新的代碼和新的方法發佈在我的答案。 –

+0

親愛的國王,你的方法對我來說太複雜了,我寫了一個輕量級的方法,但有另一個問題,我在我的文章中提到過 –

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