winform .net最好的方法,如果你想在datagridview中显示图像 [英] winform .net best way if you want to display images in a datagridview
问题描述
net webdeveloper,通常不会制作任何win32应用程序。但现在我必须。我有一个约2000个条目的列表。
每个条目应该显示为一个带有文本框的标签,另一个标签和图片。我已经做了一个flowlayoutpanel,我做了一个foreach的条目,以使每个条目的标签,文本框,标签和图片框的面板。
net webdeveloper and usually don't make any win32 apps. but now i have to. i have a list with about 2000 entries. each entry should be displayed as, a label with textbox another label and picture. i have made this with a flowlayoutpanel and i did a foreach on the entries to make a panel for each entry with the label, textbox, label and a picturebox.
现在我当它超过1000个条目时,会出现渲染问题。
所以我已经看到我应该使用listview或datagridview。
now i have rendering issues when it comes above 1000 entries. so i have read that i should use a listview or datagridview.
现在我有一个datagridview这样:
now i have a datagridview like this:
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选项和面板,我曾经在那里更快。我如何解决这个问题?
but the thing is that a bitmap on a datagridview is really slow! the picturebox option and panels which i had before where much faster. how do i resolve this?
第二个问题是:当我想跟踪第二列所做的更改时,需要哪个事件?
the second question is: which event do i need when i want to track the changes made in the 2nd column?
ow一件事:图像在线可用,因此'pd.ProductImage'是一个url
ow one thing: the images are online available so the 'pd.ProductImage' is an 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
}
}
推荐答案
使图像加载异步,然后强制单元格刷新。您可以将您的foreach代码调用到ThreadPool中,如...
Do the image load asyncrhonously then force a refresh of the cell. You can put your foreach code into a call to the ThreadPool, something like...
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(...)
}
}
编辑:这是我在Form构造函数内测试的一个示例代码...
here is a sample code that I tested inside the Form constructor...
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;
....并在单元格末端编辑代码:
.... and in the cell end edit code:
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;
});
}
这篇关于winform .net最好的方法,如果你想在datagridview中显示图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!