あなたはDataGridViewの中に画像を表示したい場合はWinフォーム.netの最良の方法

StackOverflow https://stackoverflow.com/questions/1906534

質問

通常、

ネットwebdeveloperとはどんなのWin32アプリケーションを作成していません。しかし、今私がしなければなりません。私は約2000のエントリのリストを持っています。 各エントリには、テキストボックス、別のラベルと絵でラベルとして表示する必要があります。私はflowlayoutpanelでこれを作っていると私は、ラベル、テキストボックス、ラベルとのPictureBoxと、各エントリのためのパネルを作るためのエントリにforeachのをやっています。

それは1000のエントリの上に来たときに、今私は問題をレンダリングしています。 ので、私はリストビューまたは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番目の質問です:私は2番目の列に加えられた変更を追跡したいとき、私はどのイベント必要なのです。

一つのことOW:「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
        }
    }
役に立ちましたか?

解決

画像負荷がasyncrhonously、セルのリフレッシュを強制してください。あなたは、ThreadPoolの呼び出しに

...のようなものを、あなたのforeachのコードを置くことができます
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(...)
 }
}
<時間>

編集:ここで私は、フォームのコンストラクタ内でテストしたサンプル・コードは...

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

他のヒント

// 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;
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top