2009-12-15 1 views
0

net webdeveloper и обычно не делайте никаких приложений win32. но теперь я должен. У меня есть список с около 2000 записей. каждая запись должна отображаться как метка с текстовым полем с другой меткой и изображением. я сделал это с flowlayoutpanel, и я сделал foreach в записях, чтобы сделать панель для каждой записи с меткой, текстовым полем, ярлыком и кадром.winform .net лучший способ, если вы хотите отображать изображения в datagridview

теперь у меня есть проблемы с рендерингом, когда он превышает 1000 записей. , поэтому я прочитал, что должен использовать listview или datagridview.

теперь у меня есть DataGridView, как это:

DataGridView dgv = new DataGridView(); 
dgv.AutoSize = true; 
dgv.ScrollBars = ScrollBars.Vertical; 

System.Data.DataTable dt = new System.Data.DataTable(); 
DataColumn dc1 = new DataColumn("Code", typeof(string)); 
dc1.ReadOnly = true; 
dt.Columns.Add(dc1); 
dt.Columns.Add(new DataColumn("Quantity", typeof(int))); 
DataColumn dc3 = new DataColumn("Price", typeof(string)); 
dc3.ReadOnly = true; 
dt.Columns.Add(dc3); 
dt.Columns.Add(new DataColumn("Image", typeof(Bitmap))); 

foreach (Product pd in products) 
{ 
     DataRow dr = dt.NewRow(); 
     dr["Code"] = pd.ProductCode; 
     dr["Quantity"] = pd.ProductQuantity; 
     dr["Price"] = "€ " + String.Format("{0:0,00}", pd.ProductResalePrice.ToString()); 

     dr["Image"] = BitmapFromWeb(pd.ProductImage); 
     dt.Rows.Add(dr); 
} 

dt.AcceptChanges(); 
dgv.RowTemplate.Height = 50; 
dgv.DataSource = dt; 

, но дело в том, что точечный рисунок на DataGridView очень медленно! опцию Picturebox и панели, которые у меня были раньше, где намного быстрее. как я могу это решить?

Второй вопрос: какое событие мне нужно, когда я хочу отслеживать изменения, сделанные во 2-й колонке?

вл одно: изображения онлайн доступны, так что «pd.ProductImage» является URL

private static Bitmap BitmapFromWeb(string URL) 
    { 
     try 
     { 
      HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(URL); 
      myRequest.Method = "GET"; 
      HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse(); 
      System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(myResponse.GetResponseStream()); 
      myResponse.Close(); 

      return bmp; 
     } 
     catch (Exception ex) 
     { 
      return null; // if for some reason we couldn't get to image, we return null 
     } 
    } 

ответ

4

ли загрузка изображения asyncrhonously затем принудительно обновить клетки. Вы можете поместить свой код Еогеасп в вызове ThreadPool, что-то вроде ...

ThreadPool.QueueUserWorkItem(delegate 
{ 
foreach (DataRow row in dt) 
{ 
    row["Image"] = BitmapFromWeb(Products[row["Code"]].ProductImage); 
    //maybe a call to invalidate here, remember to do Control.Invoke(...) 
} 
} 

Edit: вот пример кода, который я тестировал внутри формы конструктора ...

 DataTable t= new DataTable(); 
     t.Columns.Add("id"); 
     t.Columns.Add("uri"); 
     t.Columns.Add(new DataColumn("Img",typeof(Bitmap))); 

     Bitmap b = new Bitmap(50, 15); 
     using (Graphics g = Graphics.FromImage(b)) 
     { 
      g.DrawString("Loading...", this.Font, new SolidBrush(Color.Black), 0f,0f); 
     } 

     t.Rows.Add(new object[] { "1", "http://farm1.static.flickr.com/88/377522544_c4774f15cc_s.jpg", b }); 
     t.Rows.Add(new object[] { "2", "http://farm1.static.flickr.com/175/377522405_2c505def99_s.jpg", b }); 
     t.Rows.Add(new object[] { "3", "http://farm1.static.flickr.com/185/377524902_72f82e2db9_s.jpg", b }); 
     t.Rows.Add(new object[] { "4", "http://farm1.static.flickr.com/136/377524944_d011abf786_s.jpg", b }); 
     t.Rows.Add(new object[] { "5", "http://farm1.static.flickr.com/137/377528675_d3b9d541fb_s.jpg", b }); 
     dataGridView1.DataSource = t; 
     ThreadPool.QueueUserWorkItem(delegate 
     { 
      foreach (DataRow row in t.Rows) 
      { 
       HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(row["uri"].ToString()); 
       myRequest.Method = "GET"; 
       HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse(); 
       System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(myResponse.GetResponseStream()); 
       myResponse.Close(); 

       row["Img"] = bmp; 
      } 
     }); 

     dataGridView1.CellEndEdit += dataGridView1_CellEndEdit; 

.... и в конце ячейки кода редактирования:

private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e) 
    { 
     string value = dataGridView1.Rows[e.RowIndex].Cells["uri"].Value.ToString(); 
     ThreadPool.QueueUserWorkItem(delegate 
     { 
       HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(value); 
       myRequest.Method = "GET"; 
       HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse(); 
       System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(myResponse.GetResponseStream()); 
       myResponse.Close(); 
       dataGridView1.Rows[e.RowIndex].Cells["Img"].Value=bmp; 
     }); 
    } 
+0

благодаря jmserv но я новичок, когда дело доходит до кодирования win32. что вы имеете в виду под контролем. и вы знаете, как отслеживать изменения в текстовом поле 2-го столбца –

+0

hello jmservera, это намного быстрее, но он показывает почти на каждой строке одно и то же изображение. я новичок в потоковом ... извините –

+0

, тогда просмотрите, что вы отправляете в свой битмапфромный код, я не тестировал код, который я написал только как псевдокод C#. – jmservera

1
// table is DataTable object declared as member in my form class 
table = new DataTable(); 
table.Columns.Add(new DataColumn("Column1", typeof(string))); 
table.Columns.Add(new DataColumn("Column2", typeof(string))); 
table.Columns.Add(new DataColumn("Column3", typeof(System.Drawing.Bitmap))); 

dataGridView1.DataSource = table; 
+0

Lol, вы ответили нитью с декабря 2009 года! с синхронным решением вместо async –