Alternative solution of Treeview. bringlateral view method in WPF
Zhou yinhui
Treeview in WPF. the bringshortview () method is not so easy to use and will not work in many cases. Here is an alternative solution. Calling the selectitem () method can expand and present the specified item on the Treeview:
Public static class treeviewhelper
{
/// <Summary>
/// Expands all children of a Treeview
/// </Summary>
/// <Param name = "Treeview"> the Treeview whose children will be expanded </param>
Public static void expandall (this Treeview)
{
Expandsubcontainers (Treeview );
}
/// <Summary>
/// Expands all children of a Treeview or treeviewitem
/// </Summary>
/// <Param name = "parentcontainer"> the Treeview or treeviewitem containing the children to expand </param>
Private Static void expandsubcontainers (itemscontrol parentcontainer)
{
Foreach (Object item in parentcontainer. Items)
{
Treeviewitem currentcontainer = parentcontainer. itemcontainergenerator. containerfromitem (item) as treeviewitem;
If (currentcontainer! = NULL & currentcontainer. Items. Count> 0)
{
// Expand the item
Currentcontainer. isexpanded = true;
// If the item's children are not generated, they must be expanded
If (currentcontainer. itemcontainergenerator. status! = Generatorstatus. containersgenerated)
{
// Store the event handler in a variable so we can remove it (in the handler itself)
Eventhandler Eh = NULL;
Eh = new eventhandler (delegate
{
// Once the children have been generated, expand those children's children then remove the event handler
If (currentcontainer. itemcontainergenerator. Status = generatorstatus. containersgenerated)
{
Expandsubcontainers (currentcontainer );
Currentcontainer. itemcontainergenerator. statuschanged-= eh;
}
});
Currentcontainer. itemcontainergenerator. statuschanged + = eh;
}
Else // otherwise the children have already been generated, so we can now expand those children
{
Expandsubcontainers (currentcontainer );
}
}
}
}
/// <Summary>
/// Searches a Treeview for the provided object and selects it if found
/// </Summary>
/// <Param name = "Treeview"> the Treeview containing the item </param>
/// <Param name = "item"> the item to search and select </param>
Public static void selectitem (this Treeview, object item)
{
Expandandselectitem (Treeview, item );
}
/// <Summary>
/// Finds the provided object in an itemscontrol's children and selects it
/// </Summary>
/// <Param name = "parentcontainer"> the parent container whose children will be searched for the selected item </param>
/// <Param name = "itemtoselect"> the item to select </param>
/// <Returns> true if the item is found and selected, false otherwise </returns>
Private Static bool expandandselectitem (itemscontrol parentcontainer, object itemtoselect)
{
// Check all items at the current level
Foreach (Object item in parentcontainer. Items)
{
Treeviewitem currentcontainer = parentcontainer. itemcontainergenerator. containerfromitem (item) as treeviewitem;
// If the data item matches the item we want to select, set the corresponding
// Treeviewitem isselected to true
If (item = itemtoselect & currentcontainer! = NULL)
{
Currentcontainer. isselected = true;
Currentcontainer. bring1_view ();
Currentcontainer. Focus ();
// The item was found
Return true;
}
}
// If we get to this point, the selected item was not found at the current level, so we must check the children
Foreach (Object item in parentcontainer. Items)
{
Treeviewitem currentcontainer = parentcontainer. itemcontainergenerator. containerfromitem (item) as treeviewitem;
// If children exist
If (currentcontainer! = NULL & currentcontainer. Items. Count> 0)
{
// Keep track of if the treeviewitem was expanded or not
Bool wasexpanded = currentcontainer. isexpanded;
// Expand the current treeviewitem so we can check its child treeviewitems
Currentcontainer. isexpanded = true;
// If the treeviewitem child containers have not been generated, we must listen
// The statuschanged event until they are
If (currentcontainer. itemcontainergenerator. status! = Generatorstatus. containersgenerated)
{
// Store the event handler in a variable so we can remove it (in the handler itself)
Eventhandler Eh = NULL;
Eh = new eventhandler (delegate
{
If (currentcontainer. itemcontainergenerator. Status = generatorstatus. containersgenerated)
{
If (expandandselectitem (currentcontainer, itemtoselect) = false)
{
// The assumption is that code executing in this eventhandler is the result of the parent not
// Being expanded since the containers were not generated.
// Since the itemtoselect was not found in the children, collapse the parent since it was previusly collapsed
Currentcontainer. isexpanded = false;
}
// Remove the statuschanged event handler since we just handled it (we only needed it once)
Currentcontainer. itemcontainergenerator. statuschanged-= eh;
}
});
Currentcontainer. itemcontainergenerator. statuschanged + = eh;
}
Else // otherwise the containers have been generated, so look for item to select in the children
{
If (expandandselectitem (currentcontainer, itemtoselect) = false)
{
// Restore the current treeviewitem's expanded State
Currentcontainer. isexpanded = wasexpanded;
}
Else // otherwise the node was found and selected, so return true
{
Return true;
}
}
}
}
// No item was found
Return false;
}
}