WPF扩展VisualTreeHelper_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > WPF扩展VisualTreeHelper

WPF扩展VisualTreeHelper

 2013/8/26 21:00:34  andy1987  博客园  我要评论(0)
  • 摘要:从最近做的一个WPF项目中勾出来的,对VisualTreeHelper的扩展,用于视觉树节点的查找.ps:这里有些在WPF中需要清楚1.视觉树不等于逻辑树,WPF的树概念可以参考http://msdn.microsoft.com/zh-cn/library/vstudio/ms753391(v=vs.90).aspx2.ApplyTemplate方法用于视觉树的重建,在执行某些操作时(例如查找某个树节点时候)可能因为视觉树未创建导致查找失败
  • 标签:Visua Visual

从最近做的一个WPF项目中勾出来的,对VisualTreeHelper的扩展,用于视觉树节点的查找.

ps:这里有些在WPF中需要清楚

  1.视觉树不等于逻辑树,WPF的树概念可以参考http://msdn.microsoft.com/zh-cn/library/vstudio/ms753391(v=vs.90).aspx

  2.ApplyTemplate方法用于视觉树的重建,在执行某些操作时(例如查找某个树节点时候)可能因为视觉树未创建导致查找失败,所以可以通过该方法来确保视觉树完成

 

扩展VisualTreeHelperEx

class="code_img_closed" src="/Upload/Images/2013082621/0015B68B3C38AA5B.gif" alt="" />logs_code_hide('452f9aa4-29f9-428a-b09d-b9641a2a7616',event)" src="/Upload/Images/2013082621/2B1B950FA3DF188F.gif" alt="" />
  1     public class VisualTreeHelperEx {
  2         /// <summary>
  3         /// 从指定的树,查找第一个名称等于findChildName的元素
  4         /// ps:多用于自定义模板中无法直接通过GetChildTemplate直接
  5         /// 查找的,例如DataTemplate
  6         /// </summary>
  7         /// <typeparam name="T"></typeparam>
  8         /// <param name="targetStartDPObj"></param>
  9         /// <param name="findChildName"></param>
 10         /// <returns></returns>
 11         public static T FindFirstVisualChild<T>(DependencyObject targetStartDPObj, string findChildName)
 12                where T : DependencyObject {
 13             int iChildCount = VisualTreeHelper.GetChildrenCount(targetStartDPObj);
 14             for (int i = 0; i < iChildCount; i++) {
 15                 DependencyObject childObj = VisualTreeHelper.GetChild(targetStartDPObj, i);
 16                 if (childObj != null &&
 17                     childObj is T &&
 18                     childObj.GetValue(FrameworkElement.NameProperty).ToString().Equals(findChildName)) {
 19                     return (T)childObj;
 20                 }
 21                 else {
 22                     //如果当前节点存在二级树那么继续向下查找
 23                     T childOfChild = FindFirstVisualChild<T>(childObj, findChildName);
 24                     if (childOfChild != null) {
 25                         return childOfChild;
 26                     }
 27                 }
 28             }
 29 
 30             return null;
 31         }
 32 
 33         /// <summary>
 34         /// 查找父节点,包含自身
 35         /// </summary>
 36         /// <param name="targetDpObj"></param>
 37         /// <param name="type">指定查找的目标类型</param>
 38         /// <param name="noFindChildType">查找时候是否考虑到该类型的派生类型</param>
 39         /// <returns></returns>
 40         public static DependencyObject FindAncestorByType(DependencyObject targetDpObj, Type type, bool noFindChildType) {
 41             if (targetDpObj == null) {
 42                 return null;
 43             }
 44 
 45             if (noFindChildType ? (targetDpObj.GetType() == type) : ((targetDpObj.GetType() == type) ||
 46                 targetDpObj.GetType().IsSubclassOf(type))) {
 47                 return targetDpObj;
 48             }
 49 
 50             return FindAncestorByType(GetParent(targetDpObj), type, noFindChildType);
 51         }
 52         /// <summary>
 53         /// 查找父节点
 54         /// </summary>
 55         /// <typeparam name="T"></typeparam>
 56         /// <param name="targetDpObj"></param>
 57         /// <returns></returns>
 58         public static T FindAncestorByType<T>(DependencyObject targetDpObj)
 59             where T : DependencyObject {
 60             if (targetDpObj == null) {
 61                 return default(T);
 62             }
 63 
 64             if (targetDpObj is T) {
 65                 return (T)targetDpObj;
 66             }
 67 
 68             T parentObj = default(T);
 69             parentObj = FindAncestorByType<T>(GetParent(targetDpObj));
 70             return parentObj;
 71         }
 72 
 73         /// <summary>
 74         /// 查找指定节点的父节点,向上查找
 75         /// 查找时候分别考虑了FramworkElement和FramworkContentElement两种情况
 76         /// </summary>
 77         /// <param name="targetDPObj"></param>
 78         /// <returns></returns>
 79         public static DependencyObject GetParent(DependencyObject targetDPObj) {
 80             Visual visualElement = targetDPObj as Visual;
 81             if (visualElement == null) {
 82                 return null;
 83             }
 84 
 85             DependencyObject parentObj = VisualTreeHelper.GetParent(visualElement);
 86             if (parentObj == null) {
 87                 FrameworkElement frameworkElement = targetDPObj as FrameworkElement;
 88                 if (frameworkElement != null) {
 89                     parentObj = frameworkElement.Parent;
 90                     if (parentObj == null) {
 91                         parentObj = frameworkElement.TemplatedParent;
 92                     }
 93                 }
 94             }
 95             else {
 96                 FrameworkContentElement fce = targetDPObj as FrameworkContentElement;
 97                 if (fce != null) {
 98                     parentObj = fce.Parent;
 99                     if (parentObj == null) {
100                         parentObj = fce.TemplatedParent;
101                     }
102                 }
103             }
104 
105             return parentObj;
106         }
107            
108         /// <summary>
109         /// 查找指定节点,向下查找
110         /// </summary>
111         /// <param name="targetDpObj"></param>
112         /// <param name="type"></param>
113         /// <param name="noFindChildType"></param>
114         /// <returns></returns>
115         public static Visual FindDescendantByType(Visual targetDpObj, Type type, bool noFindChildType) {
116             if (targetDpObj == null) {
117                 return null;
118             }
119 
120             if (noFindChildType ? (targetDpObj.GetType() == type) : ((targetDpObj.GetType() == type) || (targetDpObj.GetType().IsSubclassOf(type)))) {
121                 return targetDpObj;
122             }
123 
124             Visual foundedElement = null;
125             if (targetDpObj is FrameworkElement) {
126                 //重建树,避免调用该函数前,树还没建立
127                 (targetDpObj as FrameworkElement).ApplyTemplate();
128             }
129 
130             for (int i = 0; i < VisualTreeHelper.GetChildrenCount(targetDpObj); i++) {
131                 Visual tempvisual = VisualTreeHelper.GetChild(targetDpObj, i) as Visual;
132                 foundedElement = FindDescendantByType(tempvisual, type, noFindChildType);
133                 if (foundedElement != null) {
134                     break;
135                 }
136             }
137 
138             return foundedElement;
139         }
140 
141         /// <summary>
142         /// 通过指定依赖项属性和值查找向下查找指定的节点
143         /// </summary>
144         /// <param name="targetDpObj"></param>
145         /// <param name="dp"></param>
146         /// <param name="value"></param>
147         /// <returns></returns>
148         public static Visual FindDescendantByProperty(Visual targetDpObj, DependencyProperty dp, object value) {
149             if (targetDpObj == null)
150                 return null;
151             if (targetDpObj.GetValue(dp).Equals(value)) {
152                 return targetDpObj;
153             }
154 
155             Visual foundedElement = null;
156             if (targetDpObj is FrameworkElement) {
157                 (targetDpObj as FrameworkElement).ApplyTemplate();
158             }
159 
160             for (int i = 0; i < VisualTreeHelper.GetChildrenCount(targetDpObj); i++) {
161                 Visual tempvisual = VisualTreeHelper.GetChild(targetDpObj, i) as Visual;
162                 foundedElement = FindDescendantByProperty(tempvisual, dp, value);
163                 if (foundedElement != null) {
164                     break;
165                 }
166             }
167 
168             return foundedElement;
169         }
170     }
View Code

 

发表评论
用户名: 匿名