WPF中TreeView.BringIntoView方法的替代方案
来源:互联网 发布:c语言 bcd 编辑:程序博客网 时间:2024/06/06 19:36
WPF中TreeView.BringIntoView方法的替代方案
周银辉
WPF中TreeView.BringIntoView()方法并不是那么地好用,不少时候会没有效果,这里有一个替代方案,调用SelectItem()方法可以展开并呈现TreeView上指定的Item:
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 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 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.BringIntoView();
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 to
//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 previously 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;
}
}
- WPF中TreeView.BringIntoView方法的替代方案
- WPF中TreeView的使用
- WPF中TreeView的使用
- WPF中TreeView的使用
- WPF 中Treeview 的性能问题
- WPF的TreeView中实现右键选定
- WPF中TreeView的数据帮定
- wpf 中 带checkbox的treeview
- wpf中绑定treeview
- android中 timer的替代方案!
- Swift 中AFNetworking 的替代方案 Alamofire
- Swift中NSDictionaryOfVariableBindings的替代方案
- Swift中宏#define的替代方案
- javascript中alert函数的替代方案,一个自定义的对话框的方法javascript
- 【JAVA】 Android开发之JAVA代码中FloatMath.floor方法过时的最新替代方案。
- WPF Treeview的问题
- WPF ,WinForm的TreeView
- 替代UITabBarController的方案
- 程序员的十层楼
- 一个不错的ClickOnce PPT
- XAML Guidelines
- [WPF Documents 之旅]System.Windows.Documents下的Class Diagram
- WPF Application Quality Guide
- WPF中TreeView.BringIntoView方法的替代方案
- 【讨论】不得不重视的问题:信息太多!信息太杂!
- [WPF疑难] 模式窗口被隐藏后重新显示时变成了非模式窗口
- 父窗口与子窗口的层次关系
- [WPF疑难]如何禁用WPF窗口的系统菜单(SystemMenu)
- [WPF疑难]避免窗口最大化时遮盖任务栏
- [Prism]Composite Application Guidance for WPF(10)——系列目录导航
- [Prism]Composite Application Guidance for WPF(9)——命令
- 关注分离的艺术(The Art of Separation of Concerns)