C# – Set folder view programmatically

CHECK THE UPDATE BELOW FOR BETTER SOLUTION
Making block code to accomplish a small task of Windows Explorer is always my favorite. Last week I read a thread on mycsharp.de asking about how to set folder view by code. I find this question interesting and try myself to write a small block code to set view for defined folder. As you can see in every version of Windows, we have 8 different views to choose : Extra large icons, Large icons, Medium icons, Small icons, List, Details, Tiles and Content.

Continue reading C# – Set folder view programmatically

C# – Read console output asynchronously

There are a lot of open source softwares which can be invoked through console command. If we want to integrate these programs into our software, we must handle how to input the arguments such as get the result back. If you read my blog post C# – MP3/WAV Converter with Lame/NAudio before, you’ll see how I call lame – a console application – in my application. However I didn’t explain much about how to read its output. So in this post, I’ll explain in details how we can read the output of cmd.exe.

Continue reading C# – Read console output asynchronously

C# – Use BackgroundWorker to update GUI component

In this small blog I would like to review the way to use BackgroundWorker and pass arguments to it. As all of you know that BackgroundWorker executes an operation on a separate thread. Time-consuming operations like downloads and database transactions can cause your user interface (UI) to seem as though it has stopped responding while they are running. When you want a responsive UI and you are faced with long delays associated with such operations, the BackgroundWorker class provides a convenient solution. To execute a time-consuming operation in the background, create a BackgroundWorker and listen for events that report the progress of your operation and signal when your operation is finished.

As shown in image above, the dialog has two text boxes which indicate the path of the directory and the pattern of file which we want to search for. The program will search recursively and returns the result back into list view. In the code handles event click of btnStart, you can see how we pass the argument to BackgroundWorker. The arguments will be converted to array of string and passed away.

private void btnStart_Click(object sender, EventArgs e)
{
	if (btnStart.Text == "Start")
	{
		if (!Directory.Exists(txtSearchPath.Text.Trim()))
		{
			MessageBox.Show("The Search Directory does not exist","Path Error",MessageBoxButtons.OK,MessageBoxIcon.Error);
		}
		else
		{
			if (txtSearchPattern.Text == "") txtSearchPattern.Text = "*";
			string[] args = new string[]{txtSearchPath.Text.Trim(),txtSearchPattern.Text.Trim()};
			lstFiles.Items.Clear();
			m_bgWorker.RunWorkerAsync(args);
			btnStart.Text = "Stop";
		}
	}
	else
	{
		m_bgWorker.CancelAsync();
	}
}

In the function which handles the DoWork event will filter the arguments back and start the asynchronous file search. The background thread does its work from this event. Please note that we should not write any code to update GUI in this function.

void m_bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
	string strPath = ((string[])e.Argument)[0];
	string strPattern = ((string[])e.Argument)[1];
	m_lstFiles = new List<string>();
	SearchFiles(strPath, strPattern);
	e.Result = "Found " + m_lstFiles.Count + " files";
}

private void SearchFiles(string strPath, string strPattern)
{
	string strMessage = "Parsing directory " + strPath;
	m_bgWorker.ReportProgress(0, strMessage);
	foreach (string strFileName in Directory.GetFiles(strPath, strPattern))
	{
		if (m_bgWorker.CancellationPending)
		{
			return;
		}
		else
		{
			m_lstFiles.Add(strFileName);
		}
	}

	foreach (string strDirName in Directory.GetDirectories(strPath))
	{
		if (m_bgWorker.CancellationPending)
		{
			return;
		}
		else
		{
			SearchFiles(strDirName, strPattern);
		} 
	}
}

To update GUI, we should write it in the ProcessChanged.

void m_bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
	if (bCallInProgress)
	{
		return;
	}
	else
	{
		bCallInProgress = true;
		lblMessage.Text = e.UserState.ToString();
		for (int nIndex = lstFiles.Items.Count; nIndex < m_lstFiles.Count ; nIndex++ )
		{
			lstFiles.Items.Add(m_lstFiles[nIndex]);
		}
		bCallInProgress = false;
	}
}

The bacground thread calls this event when you make a call to ReportProgress. It is OK to access user controls in the UI from this event. If you use a Progress Bar or some other control to report the tasks progress. You should avoid unnecessary calls to ReportProgress method because this causes a thread switch which is a relatively expensive in terms of processing time.
Source code: https://bitbucket.org/hintdesk/dotnet-use-backgroundworker-to-update-gui-component/