VisualTreeHelper不單單只是用來查看可視化樹結構的



關於
VisualTreeHelper這個類,你們應該都應該看到過,它是silverlight提供的一個幫助器類,經過它,以便您能夠檢查可視化樹結構。今天,咱們來經過對VisualTreeHelper的使用,來作一些比較有意思的事情,固然不止是查看可視化樹的結構,是否是有點火燒眉毛了呢?其實,也沒什麼特別離譜,固然仍是和可視化樹有關啦。其實呢,今天,咱們要使用VisualTreeHelper來經過對可視化樹結構的遍歷,「潛入」到控件的Template中去,經過對Template中元素的訪問,來改變控件的一些不直接暴露在外的屬性。


我不想ChildWindow每次都從屏幕中間彈出




最近,在作與ChildWindow相關的項目時,發現每次在調用它顯示的時候,它都從屏幕中間彈出,可是有時候,咱們須要它從特定的位置彈出,查看了下文檔,發現並無現成的能夠控制它的屬性,那是否就沒法來設置它的位置了呢?這時,該是VisualTreeHelper登場的時候了,不過在這以前,咱們得先來看一個東西,全部的奧祕也在這個東西里面,那就是ChildWindow的Template。咱們都知道,silverlight的控件都是在內部實現了它的基本模板(Template)和樣式(Style)。


那麼,咱們接下來就來看看ChildWindow的Template中到底有什麼東西。要想看它,有兩個辦法,一個是查看官方文檔,裏面有關於它的定義,還有一個方法就是經過Blend這個「神器」。在這裏,我選擇了第二個方法,咱們打開Blend,而後定位到ChildWindow鼠標右擊,選擇編輯模板--編輯副本,肯定以後,咱們就能看到以下結果:




咱們注意到,裏面有一個Grid叫作ContentRoot,這並非重點,其實,亮點在它的下面,看到了吧,在RenderTransform下有一組Transform,沒錯,找到了,奧祕就在這裏,咱們要想控制ChildWindow的位置,只要設置其中的TranslateTransform就好了,而要獲取它,則是今天的主角VisualTreeHelper要作的事情了。接下來,咱們就爲ChildWindow寫一個擴展方法SetStartLocation,經過它來設置彈出子窗口的位置:


 1    public   static   class  ChildWindowExtensions
 2      {
 3 
 4           public   static   void  SetStartLocation( this  ChildWindow childWindow,  double  x,  double  y)
 5          { 
 6          
 7              var template  =  VisualTreeHelper.GetChild(childWindow,  0 as  FrameworkElement;
 8 
 9              var contentRoot  =  template.FindName( " ContentRoot " as  FrameworkElement;
10 
11              var group  =  contentRoot.RenderTransform  as  TransformGroup;
12 
13              TranslateTransform translateTransform  =   null ;
14 
15               foreach  (var transform  in  group.Children.OfType < TranslateTransform > ())
16              {
17 
18                  translateTransform  =  transform;
19 
20              }
21 
22               //  設置初始位置
23 
24              translateTransform.X  =  x;
25 
26              translateTransform.Y  =  y;
27 
28          }
29          
30          
31          
32         
33 
34          }



上面的代碼經過VisualTreeHelper來獲得可視化樹的結構,而後進一步找到模板中咱們須要的屬性,最後設置它就好了,因而,咱們就能在實際中使用它了,咱們在主頁面中添加

一個Button,並添加Click事件,在Click事件中生成ChildWindow對象並設置它的初始位置,最後show這個窗體:



 ch  =   new  ChildWindow1();
ch.SetStartLocation(
100 100 );
            ch.Show();

 可是,運行後,當你點擊Button的時候,會拋出一個異常,這是由於,此時ChildWindow尚未產生在可視化樹上,因此你必須在它完成佈局初始化,併產生在可視化樹上的時候

才能,經過VisualTreeHelper找到須要的屬性,咱們修改代碼以下:

 1    private   void  button1_Click( object  sender, RoutedEventArgs e)
 2          {
 3              ch  =   new  ChildWindow1();
 4              ch.Show();
 5              ch.Loaded  +=   new  RoutedEventHandler(ch_Loaded);
 6            
 7             
 8          }
 9 
10           void  ch_Loaded( object  sender, RoutedEventArgs e)
11          {
12              ch.SetStartLocation( 100 100 );
13          }
14 
 這樣,當你再點擊Button的時候,子窗體將會在你設定的位置彈出,而不是在中心彈出。:)

相關文章
相關標籤/搜索