Created
September 27, 2012 17:19
-
-
Save killnine/3795230 to your computer and use it in GitHub Desktop.
Asynchronous TreeView-builder Proof-Of-Concept
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using System.Linq; | |
using System.Threading; | |
using System.Threading.Tasks; | |
using System.Windows.Forms; | |
namespace View | |
{ | |
public partial class Form1 : Form | |
{ | |
public Form1() | |
{ | |
InitializeComponent(); | |
PopulateTree(SeedCategories()); | |
} | |
/// <summary> | |
/// Makes up a bunch of categories for testing. | |
/// </summary> | |
/// <returns></returns> | |
private static IEnumerable<Category> SeedCategories() | |
{ | |
IList<Category> categoryList = new List<Category>(); | |
//Create a bunch of categories | |
for(int catId= 0; catId < 25; catId++) | |
{ | |
Category category = new Category(catId, "category" + catId); | |
categoryList.Add(category); | |
} | |
return categoryList; | |
} | |
/// <summary> | |
/// Asynchronously populates the treeView in the UI. Sets the UI to indicate 'loading...', | |
/// followed by updating the TreeView once all the categories and subcategories have been | |
/// populated | |
/// </summary> | |
/// <param name="categories">List of categories to add to the treeView</param> | |
private void PopulateTree(IEnumerable<Category> categories) | |
{ | |
//Set tree to 'loading' state | |
categoryTreeView.Nodes.Clear(); | |
categoryTreeView.Nodes.Add("Loading..."); | |
//Start the long, hard task of populating everything | |
Task<TreeNode[]> t = Task<TreeNode[]>.Factory.StartNew(() => PopulateTreeNodes(categories)); | |
t.ContinueWith(x => UpdateUI(x.Result), TaskScheduler.FromCurrentSynchronizationContext()); | |
} | |
/// <summary> | |
/// Goes through each category and populates its subcategories. | |
/// </summary> | |
/// <param name="categories">The categories.</param> | |
/// <returns>TreeNode array that can be added to the UI element later</returns> | |
private static TreeNode[] PopulateTreeNodes(IEnumerable<Category> categories) | |
{ | |
IList<TreeNode> treeNodes = categories.Select(GetSubcategories).ToList(); | |
return treeNodes.ToArray(); | |
} | |
/// <summary> | |
/// Gets the subcategories, simulating a long-running process | |
/// </summary> | |
/// <param name="category">The category.</param> | |
/// <returns>Sub-category tree node</returns> | |
private static TreeNode GetSubcategories(Category category) | |
{ | |
//Create some made-up variables to make it interesting | |
int sleepTime = category.Id * 10 < 250 ? category.Id * 10 : 250; | |
int numberOfSubcategories = category.Id < 5 ? category.Id : category.Id % 5; | |
//Sleep to imitate long-running process | |
Thread.Sleep(sleepTime); | |
//Create the actual TreeNode | |
TreeNode node = new TreeNode(category.Name); | |
for(int i =0; i < numberOfSubcategories; i++) | |
{ | |
TreeNode childNode = new TreeNode("ChildNode" + category.Id + "_" + i); | |
node.Nodes.Add(childNode); | |
} | |
return node; | |
} | |
/// <summary> | |
/// Updates the TreeNode UI element. | |
/// </summary> | |
/// <param name="nodes">The nodes to add to the UI.</param> | |
private void UpdateUI(TreeNode[] nodes) | |
{ | |
//Clear out previous 'Loading...' node | |
categoryTreeView.Nodes.Clear(); | |
//Populate with new list of nodes, like a boss | |
categoryTreeView.Nodes.AddRange(nodes); | |
} | |
} | |
/// <summary> | |
/// Category class | |
/// </summary> | |
public class Category | |
{ | |
public int Id { get; private set; } | |
public string Name { get; private set; } | |
public Category(int id, string name) | |
{ | |
Id = id; | |
Name = name; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment