原文:WPF中TreeView.BringIntoView方法的替代方案

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方法的替代方案的更多相关文章

  1. WPF中TreeView控件SelectedItemChanged方法的MVVM绑定

    问题描述:左侧treeview控件中点击不同类别的节点时,右侧的页面会显示不同的权限.比如对于My Publications,拥有Modify和Delete两种权限,对于My Subscription ...

  2. WPF中TreeView的使用

    因为项目中需要用到TreeView控件,由于是第一次在WPF中用到,因此事先在网上搜了很多关于数据绑定的方法介绍,个人经过实际应用,觉得WPF中的HierarchicalDataTemplate定义模 ...

  3. WPF中TreeView单击展开其子元素以及点击一个元素展开其他元素收起

    TreeView单击展开其子元素: 在WPF的TreeView控件中,要想展开它的子元素,我们必须要鼠标左键点两下或者右键点一下,那么我们怎样实现左键点一下就使它展开呢? Xaml: <Grid ...

  4. WPF中TreeView控件数据绑定和后台动态添加数据(二)

    写在前面:在(一)中,介绍了TreeView控件MVVM模式下数据绑定的方法.在这篇文章中,将总结给节点添加事件的方法,这样说有些不对,总之实现的效果就是点击某个节点,将出现对应于该节点的页面或者数据 ...

  5. WPF中TreeView控件数据绑定和后台动态添加数据(一)

    数据绑定: 更新内容:补充在MVVM模式上的TreeView控件数据绑定的代码. xaml代码: <TreeView Name="syntaxTree" ItemsSourc ...

  6. WPF中TreeView控件的使用案例

    WPF总体来说还是比较方便的,其中变化最大的主要是Listview和Treeview控件,而且TreeView似乎在WPF是一个备受指责的控件,很多人说他不好用.我这个demo主要是在wpf中使用Tr ...

  7. WPF中TreeView的+-号和连线style的一种实现

    最近又开始跟WPF打交道,项目里面用到了TreeView这个控件.然后需要有一个连线的外观就像是这样 二话不说,百度了一下,找到一个实现, 通道. 把代码拷贝到项目里面,跑了一下,看上去还不错.但是这 ...

  8. 在WPF中使用变通方法实现枚举类型的XAML绑定

    问题缘起 WPF的分层结构为编程带来了极大便利,XAML绑定是其最主要的特征.在使用绑定的过程中,大家都普遍的发现枚举成员的绑定是个问题.一般来说,枚举绑定多出现于与ComboBox配合的情况,此时我 ...

  9. WPF中三种方法得到当前屏幕的宽和高

    WPF程序中的单位是与设备无关的单位,每个单位是1/96英寸,如果电脑的DPI设置为96(每个英寸96个像素),那么此时每个WPF单位对应一个像素,不过如果电脑的DPI设备为120(每个英寸120个像 ...

随机推荐

  1. Linux 目录结构学习与简析 Part2

    linux目录结构学习与简析 by:授客 QQ:1033553122 ---------------接Part 1-------------- #1.查看CPU信息 #cat /proc/cpuinf ...

  2. loadrunner 场景设计-集合点设置

    场景设计-集合点设置 by:授客 QQ:1033553122 1  作用 通过让多用户在同一时间点上进行并发操作来测试系统的并发处理的能力 2  实现 通过集合点函数来实现. 注意:集合点经常和事务结 ...

  3. 修改eclipse的背景色(转载)

    eclipse操作界面默认颜色为白色.对于我们长期使用电脑编程的人来说,白色很刺激我们的眼睛,所以我经常会改变workspace的背景色,使眼睛舒服一些. 设置方法如下: 1.打开window-> ...

  4. OpenCV 填充(ROI)+模糊操作

    1.ROI 操作 src = cv.imread('./1.jpg') cv.imshow('src',src) dst = src[40:240,100:300] gray = cv.cvtColo ...

  5. js replace替换 忽略大小写问题

    实现就是控制台的内容“abc”,但是后台返回的是“ABC”,这个时候在前台遍历,需要将后台返回的在控制台标红. 当然控制台可以是 abc Abc等大小写混合,以下代码都可替换. var flagnew ...

  6. python第九十一天----第十六周作业

    实现功能: 1.非编辑模式 ​ 可以对每行进行选择,全选,取消,反选 : 2.编辑模式 ​ 进入编辑模式时: 如果行被选中,则被选中的行变为可编辑状态,未选中则不改变 ​ 退出编辑模式时: 保存所有的 ...

  7. 4.2Python数据类型(2)之布尔类型

    返回总目录 目录: 1.布尔类型的概念和分类: 2.布尔类型的本质 3.布尔类型的应用 (一)布尔类型的概念和分类: (1)概念: 布尔类型(bool)就是用于判断真假的数据类型 (2)分类: Pyt ...

  8. PHP LAMP环境搭建及网站配置流程(完整版)

    心血来潮想做一个自己的博客网站,写一些文章做技术分享,平时遇到的一些问题的解决办法都记录下来,网站搭建成功,那么第一篇博客自然就是整个网站的搭建以及域名的注册.备案.解析流程,总共分为以下几步: 1. ...

  9. 怎样将本地web项目部署到腾讯云服务器上?

    怎样将本地web项目部署到腾讯云服务器上? 1.本地计算机的工作: (1).用eclipse新建一个web项目,然后在webcontent下新建一个index.html,然后在本地部署到Tomcat服 ...

  10. UVA506-System Dependencies(拓扑序)

    Problem UVA506-System Dependencies Accept:285  Submit:2824 Time Limit: 3000 mSec Problem Description ...