I am totally new to WPF, I have created a simple WPF app that lists whole drive structure (folder, files) to a TreeView, since this process takes a while I tried to use a thread to run the GetFolderTree() method and prevent the UI from becoming unresponsive, however I am facing some problems, I have created a Class named FolderBrowser where I have all that drive structure gathering code, inside that class I create a new instance of TreeViewItem which holds drive structure at the end it is used as return value to populate the TreeView, This is the code:
using System.IO;
using System.Windows.Controls;
namespace WpfApplication
{
public class FolderBrowser
{
private TreeViewItem folderTree;
private string rootFolder;
public FolderBrowser(string path)
{
rootFolder = path;
folderTree = new TreeViewItem();
}
private void GetFolders(DirectoryInfo di, TreeViewItem tvi)
{
foreach (DirectoryInfo dir in di.GetDirectories())
{
TreeViewItem tviDir = new TreeViewItem() { Header = dir.Name };
try
{
if (dir.GetDirectories().Length > 0)
GetFolders(dir, tviDir);
tvi.Items.Add(tviDir);
GetFiles(dir, tviDir);
}
//catch code here
}
if (rootFolder == di.FullName)
{
folderTree.Header = di.Name;
GetFiles(di, folderTree);
}
}
private void GetFiles(DirectoryInfo di, TreeViewItem tvi)
{
foreach (FileInfo file in di.GetFiles())
{
tvi.Items.Add(file.Name);
}
}
public TreeViewItem GetFolderTree()
{
DirectoryInfo di = new DirectoryInfo(rootFolder);
if (di.Exists)
{
GetFolders(di, folderTree);
}
return folderTree;
}
}
}
How could I create new control instances inside this new thread?
Thanks in advance
You can’t interact with the UI in any thread but the UI thread, but you can use the UI Dispatcher object to execute a callback inside the UI thread:
A more “clean” way of obtaining the dispatcher is to pass it from the UI object to the thread/class that spawns the thread, when you are creating it.
Edit:
I recommend HCL’s solution over mine. However, you asked in comments how to get this to work without duplicating this big nasty block of code everywhere:
In your constructor, take a reference to a
Dispatcherobject, and store it within your class.Then make a method like this:
And call it like this:
You can wrap large blocks of code this way:
If you try to push too much of this code back into the UI, though, it will be no different than if you executed all the code within the UI thread, and will still hang the UI.
However, HCL’s suggestion of populating a custom tree structure, instead of having that code know anything about UI controls, is much better 🙂