2011-01-22 16 views
1

(英国)郵便番号に基づいてGoogleの静的地図からオンデマンドで取り込んだ画像を読み込もうとしています。別のスレッドのPictureBoxに画像を読み込む

私はクライアントがあり、クライアントにはアドレスがあるとします。クライアントのプロパティの1つはPostCodeです。私はクライアントをロードするフォームを持っています。このフォームのコンストラクタにクライアントIDを送り、LINQ 2 SQLを使用してアドレスを含むあらゆる種類の情報をロードします。

private void LoadBranchDetails() { 
    Text_Update_BI_Name.Text = Branch.BranchNumber; 
    Text_Update_BI_Manager.Text = String.Format("{0} {1}", Branch.PharmacyManager.FirstName, Branch.PharmacyManager.LastName); 
    DropDownList_Update_BI_Coordinator.SelectedValue = Branch.CoordinatorID; 
    DropDownList_Update_BI_ComputerSystem.SelectedValue = Branch.ComputerSystemID; 
    Text_Update_BI_Phone.Text = Branch.PhoneNumber; 
    Text_Update_BI_Fax.Text = Branch.FaxNumber; 

    Address BranchAddress = Branch.Contact.Addresses.FirstOrDefault(); 
    Text_Update_AI_House.Text = BranchAddress.HouseNumber; 
    Text_Update_AI_Street.Text = BranchAddress.Street; 
    Text_Update_AI_Area.Text = BranchAddress.Area; 
    Text_Update_AI_Post.Text = BranchAddress.PostCode; 
    DropDownList_Update_AI_City.SelectedValue = BranchAddress.City.OID; 

    MaskedText_Update_OI_NoPharmacist.Value = Branch.NumberOfPharmacists; 
    MaskedText_Update_OI_NoDispensers.Value = Branch.NumberOfDispensers; 
    MaskedText_Update_OI_NoMonFri.Value = Branch.NumberOfItemsMondayToFriday; 
    MaskedText_Update_OI_NoSat.Value = Branch.NumberOfItemsSaturday; 
    MaskedText_Update_OI_NoSun.Value = Branch.NumberOfItemsSunday; 
    MaskedText_Update_OI_NoAddicts.Value = Branch.NumberOfAddicts; 
    MaskedText_Update_OI_NoSupervised.Value = Branch.Supervised; 
    MaskedText_Update_OI_NoUnsupervised.Value = Branch.Unsupervised; 

    Check_Update_OI_ConfRoom.Checked = Branch.ConsultationRoom; 

    try {   
    PictureGoogleMaps.Image = GoogleAddressInfo.FetchMapInfo(Text_Update_AI_Post.Text).GoogleStaticMap; 

    } catch (Exception) { 
    PictureGoogleMaps.Image = Resources.DefaultGoogleMap; 

    } 
} 

PictureGoogleMapsにイメージをロードする行が呼び出されたときに「.GoogleStaticMap」プロパティは、Googleの静止画像を生成してUIでハングの原因となります。インターネットを検索する際

は、私は、この便利な例を見つけました:

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 

     // Declare a list of URLs and their respective picture boxes 
     var items = new Dictionary<string, PictureBox> 
     { 
      { "http://www.google.com/logos/spring09.gif", new PictureBox() { Top = 0, Width = 300, Height = 80 } }, 
      { "http://www.google.com/logos/stpatricks_d4gwinner_eo09.gif", new PictureBox() { Top = 100, Width = 300, Height = 80 } }, 
      { "http://www.google.com/logos/schiaparelli09.gif", new PictureBox() { Top = 200, Width = 300, Height = 80 } }, 
      { "http://www.google.com/logos/drseuss09.gif", new PictureBox() { Top = 300, Width = 300, Height = 80 } }, 
      { "http://www.google.com/logos/valentines09.gif", new PictureBox() { Top = 400, Width = 300, Height = 80 } }, 
      { "http://www.google.com/logos/unix1234567890.gif", new PictureBox() { Top = 500, Width = 300, Height = 80 } }, 
      { "http://www.google.com/logos/charlesdarwin_09.gif", new PictureBox() { Top = 600, Width = 300, Height = 80 } }, 
     }; 

     foreach (var item in items) 
     { 
      var worker = new BackgroundWorker(); 
      worker.DoWork += (o, e) => 
      { 
       // This function will be run on a background thread 
       // spawned from the thread pool. 
       using (var client = new WebClient()) 
       { 
        var pair = (KeyValuePair<string, PictureBox>)e.Argument; 
        e.Result = new KeyValuePair<PictureBox, byte[]>(pair.Value, client.DownloadData(pair.Key)); 
       } 
      }; 
      worker.RunWorkerCompleted += (o, e) => 
      { 
       // This function will be run on the main GUI thread 
       var pair = (KeyValuePair<PictureBox, byte[]>)e.Result; 
       using (var stream = new MemoryStream(pair.Value)) 
       { 
        pair.Key.Image = new Bitmap(stream); 
       } 
       Controls.Add(pair.Key); 
      }; 
      worker.RunWorkerAsync(item); 
     } 
    } 
} 

は今、私はちょうどforループを削除し、私のシナリオでこれを使用する方法を理解する必要があります。何か案は?

サンプルコードはlinkに由来します。

ありがとうございました。

答えて

1
public partial class Form1 : Form 
    {   
     private BackgroundWorker imageLoader; 

     public Form1() 
     { 
      InitializeComponent(); 

      this.imageLoader = new BackgroundWorker(); 
      this.imageLoader.DoWork += HandleOnImageLoaderDoWork; 
      this.imageLoader.RunWorkerCompleted += HandleImageLoaderOnRunWorkerCompleted; 

      this.LoadUserDetails(1); 
     } 

     private void LoadUserDetails(Int32 userID) 
     { 
      this.imageLoader.RunWorkerAsync(userID.ToString()); 
      // get the user details 
      // populate the UI controls with the data.... 
     } 

     private void HandleImageLoaderOnRunWorkerCompleted(Object sender, RunWorkerCompletedEventArgs e) 
     { 
      this.pictureBox1.Image = (Image)e.Result; 
     } 

     private void HandleOnImageLoaderDoWork(Object sender, DoWorkEventArgs e) 
     { 
      // simulate a web request for an image; 
      Thread.Sleep(3000); 
      Image image = Image.FromFile(@"test.jpg"); 
      e.Result = image; 
     } 
    } 

はまた、あなたがバックグラウンド操作が...プロセスでのPictureBoxで初期画像(loading.gif)のようなもので、いくつかのUIの通知を示していることを確認してください。

+0

ありがとうございます。これはうまく動作します。また、私はRunWorkerAsyncにユーザーIDを送ったことに気づいた:this.imageLoader.RunWorkerAsync(userID.ToString());今私は、このアプローチを使用して、データそのものを画像と共にロードできるかどうか疑問に思います。 – DoomerDGR8

+1

はい、できます。しかし、コードをきれいに保つために、(データを保持する)型を作成し、それをDoWorkとRunWorkerCompletedイベントハンドラの間で渡すことができます。 –

1

foreachループを削除するのは難しいですか?単一の画像をロードするだけで、foreachループを削除して、画像のURLとターゲットのピクチャボックスをバックグラウンドワーカーに渡すだけです。

+0

いいえ、ForEachを削除するのは簡単でした。私はループの最後の行で少し混乱していた:worker.RunWorkerAsync(item); – DoomerDGR8

関連する問題