成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

詳解WPF中VisualTree增加Visual的處理方法

開發 后端
本文將介紹的是WPF中VisualTree增加Visual的處理方法,希望對大家用好WPF有所幫助。

這里我們將介紹WPF中VisualTree增加Visual的處理方法,首先我們將從一個典型的問題開始講述。希望這些討論能對大家有所幫助。

作為一個WPF控件開發者,我在工作中經常遇到如本文標題所示的問題。其實,這個問題并不是很難,只是在操作上有些繁瑣。本文將嘗試對這個問題進行解答,并且對相關的一些技術細節加以探討。

#T#

先從我遇到的一個典型的問題開始吧:寫一個MyElement類,要求如下:

從FrameworkElement繼承

增加一個Button到它的VisualTree上

在Visual上有一個AddVisualChild方法,相信很多剛接觸這個方法的同學們(好吧,至少我是這樣)都會“顧名思義”地認為這個方法就可以解決本文的問題。再加上MSDN上也給出了一個例子來“火上澆油”一把。于是,一陣竊喜之后,我興奮地敲出了以下代碼:

  1. Code  
  2.  class MyElement : FrameworkElement  
  3. {  
  4. private Button _button = new Button() { Content = "I'm a Button!"};  
  5.  
  6. public MyElement()  
  7. {  
  8. this.AssembleVisualChildren();  
  9. }  
  10.  
  11. private void AssembleVisualChildren()  
  12. {  
  13. this.AddVisualChild(this._button);  
  14. }  
  15. protected override int VisualChildrenCount  
  16. {  
  17. get 
  18. {  
  19. return 1;  
  20. }  
  21. }  
  22. protected override Visual GetVisualChild(int index)  
  23. {  
  24. return this._button ;  
  25. }  
  26.  } 

然后將這個MyElement加入測試窗口,代碼如下:

  1. Code     
  2. <Window      
  3. x:Class="AddVisualChildTest.Window1"    
  4. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    
  5. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    
  6. xmlns:loc="clr-namespace:AddVisualChildTest"    
  7. WindowStartupLocation="CenterScreen"    
  8. Title="Window1" Height="300" Width="300">    
  9. <Grid>    
  10. <loc:MyElement Margin="10"/>    
  11. </Grid>    
  12. </Window>  

運行后的結果如下:

運行結果

空空如也!嗯,被忽悠了。一陣失落、打擊之后,我的好奇心被激發了:這是為什么呢?于是我狂找資料,終于被我發現了:

實際上,在上面這個例子中,AddVisualChild這個方法只是在MyElement和Button之間建立起了一種VisualTree上的父子關系,但是并沒有將Button掛接到MyElement的VisualTree上,所以最終我們沒有在屏幕上看到這個Button。

為了將Button真正掛接到MyElement的VisualTree上,還需要額外做一件事情:在VisualTree上為這個Button分配空間并且指定位置,這個過程叫做Layout。此過程分兩個部分:一個是Measure,另一個是Arrange。這兩個過程在FrameworkElement上對應著兩個方法:MeasureOverride和ArrangeOverride方法。具體做法如下:

  1. Code  
  2. protected override Size MeasureOverride(Size availableSize)  
  3. {  
  4. if (this.VisualChildrenCount > 0)  
  5. {  
  6. UIElement child = this.GetVisualChild(0) as UIElement;  
  7. Debug.Assert(child != null); // !Assert  
  8. child.Measure(availableSize);  
  9. return child.DesiredSize;  
  10. }  
  11.  
  12. return availableSize;  
  13. }  
  14.  
  15. protected override Size ArrangeOverride(Size finalSize)  
  16. {  
  17. Rect arrangeRect = new Rect()  
  18. {  
  19. Width = finalSize.Width,  
  20. Height = finalSize.Height  
  21. };  
  22.  
  23. if (this.VisualChildrenCount > 0)  
  24. {  
  25. UIElement child = this.GetVisualChild(0) as UIElement;  
  26. Debug.Assert(child != null); // !Assert  
  27. child.Arrange(arrangeRect);  
  28. }  
  29.  
  30. return finalSize;  

再次運行程序:

再次運行程序結果

目標實現。

由此,我們可以總結出這個問題的解決方案如下:

在MyElement的構造器中調用AddVisualChild方法;

重寫VisualChildCount屬性;

重寫GetVisualChild方法;

重寫MeasureOverride方法;

重寫ArrangeOverride方法;

另外,WPF在此問題的解決上也為開發者提供了一些必要的幫助。就我所知的,有如下幾個內容:

1、Panel

 還是本文開始提到的問題,只不過要將其中的FrameworkElement換為Panel。除了上面所提到的方法,Panel為我們提供了更加方便的實現方式。代碼如下:

  1. Code  
  2.  class MyElement : Panel  
  3. {  
  4. private Button _button = new Button() { Content = "I'm a Button!" };  
  5.  
  6. public MyElement()  
  7. {  
  8. this.Children.Add(_button);  
  9. }  
  10.  
  11. protected override Size MeasureOverride(Size availableSize)  
  12. {  
  13. if (this.VisualChildrenCount > 0)  
  14. {  
  15. UIElement child = this.GetVisualChild(0) as UIElement;  
  16. Debug.Assert(child != null); // !Assert  
  17. child.Measure(availableSize);  
  18. return child.DesiredSize;  
  19. }  
  20.  
  21. return availableSize;  
  22. }  
  23. protected override Size ArrangeOverride(Size finalSize)  
  24. {  
  25. Rect arrangeRect = new Rect()  
  26. {  
  27. Width = finalSize.Width,  
  28. Height = finalSize.Height  
  29. };  
  30.  
  31. if (this.VisualChildrenCount > 0)  
  32. {  
  33. UIElement child = this.GetVisualChild(0) as UIElement;  
  34. Debug.Assert(child != null); // !Assert  
  35. child.Arrange(arrangeRect);  
  36. }  
  37.  
  38. return finalSize;  
  39. }  

之所以能這樣做的原因是Panel已經替我們將如下幾個工作封裝在了UIElementCollection(Panel的Children屬性)中:

AddVisualChild

VisualChildCount

GetVisualChild

2、VisualCollection

另外,在這個過程中,我們還可以使用一個叫做VisualCollection的類來作為所有 Visual Child的容器。這個容器構造的時候需要一個Visual類型的Parent,然后在添加、刪除Visual Child的時候,它的相應方法(Add,Remove)就會幫助我們自動調用Parent的AddVisualChild和RemoveVisualChild方法。如此一來,我們的工作量又減少了。具體的實現代碼很簡單,這里就不貼了(總得動動腦子是不?)。

原文標題:WPF:如何在VisualTree上增加Visual?

鏈接:http://www.cnblogs.com/AaronLu/archive/2009/11/09/1599348.html

責任編輯:彭凡 來源: 博客園
相關推薦

2011-05-24 15:48:24

linux軟路由路由

2009-12-28 13:28:03

WPF視頻

2009-12-24 17:57:53

WPF頁面跳轉

2009-12-28 16:00:36

WPF樣式繼承

2010-10-13 08:57:06

Visual Stud

2010-03-01 09:16:22

Visual Stud

2009-12-24 16:11:07

WPF圖像處理

2009-07-01 18:17:32

JSP處理Cookie

2009-07-01 16:52:47

增加瀏覽器Visual Stud

2010-01-27 10:32:40

Visual Stud

2009-11-24 09:00:02

Visual Stud

2009-12-28 16:10:38

WPF生成文件

2009-12-28 17:17:52

WPF導航

2010-01-14 14:12:14

Visual Stud

2010-12-16 10:00:20

QtVisual Stud

2010-02-23 09:02:00

Visual Stud

2012-04-29 11:13:14

APP

2009-10-14 09:08:23

Visual Stud

2009-09-10 09:15:38

監視程序死鎖

2009-11-04 09:16:00

Visual Stud
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 在线视频亚洲 | 亚洲aⅴ精品 | 宅男伊人| www.久草.com| www.蜜桃av | 中文字幕免费在线 | 日韩精品成人在线 | 亚洲国产精品日韩av不卡在线 | 国产激情福利 | 操久久| 一级毛片视频免费观看 | 国产一区二区观看 | 亚洲欧美一区二区三区1000 | 亚洲精品一区在线观看 | 亚洲精品国产a久久久久久 午夜影院网站 | 99亚洲视频| 欧美激情一区二区三级高清视频 | 精品一区二区三区在线观看国产 | 国产一二三区免费视频 | 国产免费一区二区三区 | 国产精品视频中文字幕 | 夜夜草 | www.国产精品 | 99热播精品 | 亚洲国产成人av好男人在线观看 | 国产夜恋视频在线观看 | 91麻豆精品国产91久久久更新资源速度超快 | 视频一区二区在线观看 | 欧美中文字幕一区二区 | 97精品国产97久久久久久免费 | 精品国产一区二区久久 | 亚洲精品成人av久久 | 久久精品99 | 欧美在线一区二区三区 | 日韩欧美中文 | 国产乱码精品一区二区三区五月婷 | 久久99这里只有精品 | 深夜福利亚洲 | 亚洲欧美激情四射 | 国产大学生情侣呻吟视频 | 国产一区二区三区在线免费观看 |