Created
April 26, 2012 02:10
-
-
Save jsonw23/2495207 to your computer and use it in GitHub Desktop.
Folder Tree WPF Control: Part 2 - Recursive Checkbox Behavior
This file contains 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
public void Add(FolderTreeItem folderTreeItem, bool include = true) | |
{ | |
if (folderTreeItem.SelectionItem == null && include) | |
{ | |
// node is checked for the first time, add a selection item | |
folderTreeItem.SelectionItem = new Item() { TreeItem = folderTreeItem, Include = include }; | |
items.Add(folderTreeItem.SelectionItem); | |
} | |
else if (folderTreeItem.SelectionItem != null && folderTreeItem.SelectionItem.Include != include) | |
{ | |
// node with a current state is checked/unchecked | |
if (!include && (folderTreeItem.Parent == null || folderTreeItem.Parent.SelectionItem == null)) | |
{ | |
// special behavior if root node is unchecked | |
items.RemoveAll(x => x.TreeItem.Equals(folderTreeItem)); | |
folderTreeItem.SelectionItem = null; | |
} | |
else | |
{ | |
// determine if this node itself was specifically checked/unchecked | |
var match = items.Where(x => x.TreeItem.Equals(folderTreeItem)).SingleOrDefault(); | |
if (match != null) | |
{ | |
// if so, adjust it's state | |
match.Include = include; | |
} | |
else | |
{ | |
// if not, add a new selection item | |
folderTreeItem.SelectionItem = new Item() { TreeItem = folderTreeItem, Include = include }; | |
items.Add(folderTreeItem.SelectionItem); | |
} | |
} | |
} | |
// process children nodes if any are loaded | |
if (folderTreeItem.FoldersLoaded) | |
{ | |
foreach (var childItem in folderTreeItem.Folders) | |
{ | |
// all children node states should be wiped out and given a reference to this nodes state | |
items.RemoveAll(x => x.TreeItem.Equals(childItem)); | |
childItem.SelectionItem = folderTreeItem.SelectionItem; | |
childItem.IsChecked = include; | |
// recurse to go as many levels deep as we can | |
// recursive calls will skip the code above because the selection item is already set here | |
Add(childItem, include); | |
} | |
} | |
// give the parent nodes either checked or indeterminate states | |
ProcessParents(folderTreeItem); | |
} | |
private void ProcessParents(FolderTreeItem folderTreeItem) | |
{ | |
if (folderTreeItem.Parent == null) | |
return; | |
bool indeterminate = false; | |
bool? current = folderTreeItem.IsChecked; | |
// walk up the tree | |
do | |
{ | |
folderTreeItem = folderTreeItem.Parent; | |
// if any of the other children have a different checkbox state, set to indeterminate | |
if (indeterminate || folderTreeItem.Folders.Any(x => x.IsChecked != current)) | |
{ | |
folderTreeItem.IsChecked = null; | |
indeterminate = true; | |
} | |
else | |
{ | |
folderTreeItem.IsChecked = current; | |
} | |
} while (folderTreeItem.Parent != null); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment