Phu Minh Pham
Phu Minh Pham

Reputation: 1055

Add strings to listbox in WPF using C# in a thread

I want to display the path of each file when a button is pressed. What I have right now is a function that iterates through a folder and displays the paths, but only when the function is finished:

public void ProcessDirectory(string targetDirectory)
{
    // Process the list of files found in the directory.
    try
    {
        var fileEntries = Directory.GetFiles(targetDirectory);

        foreach (var fileName in fileEntries)
        {
            ProcessFile(fileName);
        }
    }
    catch (Exception e){}
    // Recurse into subdirectories of this directory.
    try
    {
        var subdirectoryEntries = Directory.GetDirectories(targetDirectory);

        foreach (string subdirectory in subdirectoryEntries)
            ProcessDirectory(subdirectory);
    }
    catch (Exception e){}
}


public void ProcessFile(string path)
{
    myListBox.Items.Add(path);  
}

This means that I have to wait before I can do something else. How can I display the path of a file instantly when the function is running, so i don't have to wait before the function is finished, getting all the paths before displaying in the listbox?

Upvotes: 2

Views: 3049

Answers (2)

hcb
hcb

Reputation: 8357

This makes your method run on another thread:

public void StartProcessThread(string targetDirectory)
{
    Thread T = new Thread(new ParameterizedThreadStart(ProcessDirectory));

    T.Start(targetDirectory);
}

public void ProcessDirectory(object objTargetDirectory)
{
    string targetDirectory = (string)objTargetDirectory;

    // Process the list of files found in the directory.
    try
    {
        var fileEntries = Directory.GetFiles(targetDirectory);

        foreach (var fileName in fileEntries)
        {
            ProcessFile(fileName);
        }
    }
    catch (Exception e){}
    // Recurse into subdirectories of this directory.
    try
    {
        var subdirectoryEntries = Directory.GetDirectories(targetDirectory);

        foreach (string subdirectory in subdirectoryEntries)
            ProcessDirectory(subdirectory);
    }
    catch (Exception e){}
}


public void ProcessFile(string path)
{
    Dispatcher.Invoke(new Action(() => {
        myListBox.Items.Add(path);  
    }));
}

Upvotes: 0

Eirik
Eirik

Reputation: 4215

I don't remember where I came across this piece of code, but if you modify your ProcessFile method to something like this it will update your UI after each item is added to your list.

public void ProcessFile(string path)
{
    myListBox.Items.Add(path);
    myListBox.ScrollIntoView(myListBox.Items[myListBox.Items.Count-1]);
    Dispatcher.Invoke(new Action(delegate { }), DispatcherPriority.Background);
}

I think I remember reading somewhere that this "hack" is not recommended due to a number of other problems that might occur, but I can't remember what it was or where I read it. It does the job however.

Maybe someone else can enlighten us about what these problems are...

Upvotes: 3

Related Questions