2011-11-22 12 views
5

Ho ottenuto fino a mettere un file in un flusso da un URL. Tuttavia, puttin savefiledialog all'interno dell'evento OpenReadCompleted fornisce un'eccezione perché il savefiledialog deve essere attivato da un evento incoerente dell'utente. L'inserimento di savefiledialog NON in OpenReadCompleted restituisce un errore perché l'array di byte è vuoto, non ancora elaborato. C'è un altro modo per salvare un file per lo streaming da un uri senza usare un evento?Scarica il file da assoluto uri a flusso su SaveFileDialog

public void SaveAs() 
{ 
WebClient webClient = new WebClient(); //Provides common methods for sending data to and receiving data from a resource identified by a URI. 
     webClient.OpenReadCompleted += (s, e) => 
              { 
               Stream stream = e.Result; //put the data in a stream 
               MemoryStream ms = new MemoryStream(); 
               stream.CopyTo(ms); 
               bytes = ms.ToArray(); 
              }; //Occurs when an asynchronous resource-read operation is completed. 
     webClient.OpenReadAsync(new Uri("http://testurl/test.docx"), UriKind.Absolute); //Returns the data from a resource asynchronously, without blocking the calling thread. 

     try 
     { 
     SaveFileDialog dialog = new SaveFileDialog(); 
     dialog.Filter = "All Files|*.*"; 

     //Show the dialog 
     bool? dialogResult = dialog.ShowDialog(); 

     if (dialogResult != true) return; 

     //Get the file stream 
     using (Stream fs = (Stream)dialog.OpenFile()) 
     { 
      fs.Write(bytes, 0, bytes.Length); 
      fs.Close(); 

      //File successfully saved 
     } 
     } 
     catch (Exception ex) 
     { 
      //inspect ex.Message 
      MessageBox.Show(ex.ToString()); 
     } 

} 

risposta

7

L'approccio da adottare è quello di prima aprire il SaveFileDialog a seguito di alcune interazione con l'utente come un pulsante di scatto. Avendo avuto l'utente di determinare dove salvare il download e il metodo SaveDialog ha restituito mantenere questa istanza di SaveFileDialog a portata di mano.

Quindi si richiama il download e nel OpenReadCompleted è possibile utilizzare il metodo SaveFileDialogOpenFile per ottenere uno streaming a cui è possibile pompare il risultato.

public void SaveAs() 
{ 
    SaveFileDialog dialog = new SaveFileDialog(); 
    dialog.Filter = "All Files|*.*"; 

    bool? dialogResult = dialog.ShowDialog(); 

    if (dialogResult != true) return; 

    WebClient webClient = new WebClient(); 
    webClient.OpenReadCompleted += (s, e) => 
    { 
     try 
     {  
      using (Stream fs = (Stream)dialog.OpenFile()) 
      { 
       e.Result.CopyTo(fs); 
       fs.Flush(); 
       fs.Close(); 
      } 

     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.ToString()); 
     } 
    }; 
    webClient.OpenReadAsync(new Uri("http://testurl/test.docx"), UriKind.Absolute); 
} 

Avrete notato che non solo è il codice più pulito e più semplice, ma se l'utente finisce per annullare il SaveFileDialog non hanno sprecato il loro tempo o la larghezza di banda il download di un file.

+0

Funziona perfettamente! Perché non ci ho pensato. Probabilmente perché sono un principiante. Molte grazie. – tutu

0

ho trovato un modo semplice per scaricare il file dall'applicazione Silverlight. usa il controllo HyperLinkButton.

è possibile specificare bersaglio utilizzando anche propery "TargetName".

+1

Questo è più adatto come commento. –