2011-05-19 13 views
5

sto usando Directory.GetFiles per darmi i file mp3, e mi piacerebbe riempire un ListBox con i risultati, ma invece di fermare il programma mentre passa attraverso il metodo, posso farlo cercare e riempire il ListBox su come ottiene i file mp3?directory.GetFiles, come faccio a sputare gli oggetti mentre li trova?

Quindi quello che sto usando è la seguente (e non riesce a aggiungere uno alla al momento, è l'aggiunta di tutti in una volta quando è fatto)

private List<string> Getmp3sFromFolders(string folder) 
    { 
     List<string> fileArray = new List<string>(); 

     try 
     { 
      DirectoryInfo dir = new DirectoryInfo(folder); 
      var files = dir.EnumerateFiles("*.mp3"); 
      foreach (var file in files) 
      { 

       fileArray.Add(file.FullName); 
       Dispatcher.BeginInvoke(_AddMP3ToListbox, file.Name); 
      } 

      var directories = dir.EnumerateDirectories(); 
      foreach (var subdir in directories) 
      { 
       fileArray.AddRange(Getmp3sFromFolders(subdir.FullName)); 

      } 

      // lblFolderSearching.Content = folder.ToString(); 
     } 
     catch 
     { 

     } 
     return fileArray; 
    } 

ho aggiunto _AddMP3ToListbox = AddMP3ToListbox

aggiunge effettivamente gli mp3 alla listbox, ma lo fa tutto in una volta, non appena lo trova. come posso risolvere questo?

risposta

11

Utilizzare Directory.EnumerateFiles anziché Directory.GetFiles. EnumerateFiles restituirà i file così come sono stati trovati dal sistema, non aspettando che vengano trovati tutti.

Effettuare questa operazione su una thread in background e utilizzare Dispatcher.Invoke o Dispatcher.BeginInvoke nel thread dell'interfaccia utente poiché si trova a ciascuno di essi per aggiungerlo allo ListBox.

Ecco un rapido esempio che ho buttato insieme. Ecco il codice XAML:

<Window x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="*" /> 
      <RowDefinition Height="Auto" /> 
     </Grid.RowDefinitions> 
     <ListBox x:Name="_FileList" /> 
     <Button Grid.Row="1" Content="Go!" Click="Button_Click" /> 
    </Grid> 
</Window> 

ed ecco il code-behind:

using System; 
using System.IO; 
using System.Windows; 

namespace WpfApplication1 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     private Action<string> _AddToListBox; 

     public MainWindow() 
     { 
      InitializeComponent(); 
      _AddToListBox = AddToListBox; 
     } 

     private void Button_Click(object sender, RoutedEventArgs e) 
     { 
      Action action = Go; 
      action.BeginInvoke(null, null); 
     } 

     private void Go() 
     { 
      foreach (var file in Directory.EnumerateFiles(@"c:\windows\system32\")) 
      { 
       Dispatcher.BeginInvoke(_AddToListBox, file); 
      } 
     } 

     private void AddToListBox(string toAdd) 
     { 
      _FileList.Items.Add(toAdd); 
     } 
    } 
} 

in nessun modo fare ho intenzione per questo di essere una best practice o onnicomprensiva esempio. Ti sto solo mostrando un modo per farlo. A proposito, ho scelto la directory system32 solo perché ha un sacco di file in modo da poterlo testare. Comunque funziona ancora quasi istantaneamente sulla mia macchina.

+0

Cool, non sapevo che avessero aggiunto EnumerateFiles. –

+0

Sì. Non lo sapevo nemmeno fino a poco tempo fa. Anche in Silverlight. Decisamente utile per rendere le cose asincrone. – Tim

+0

puoi darmi un codice di esempio in C# che viene esportato in una listbox? ho provato e sto diventando tempi più lenti rispetto a GetFiles – darthwillard

Problemi correlati