日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
詳解WPF中VisualTree增加Visual的處理方法

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

作為一個(gè)WPF控件開發(fā)者,我在工作中經(jīng)常遇到如本文標(biāo)題所示的問題。其實(shí),這個(gè)問題并不是很難,只是在操作上有些繁瑣。本文將嘗試對(duì)這個(gè)問題進(jìn)行解答,并且對(duì)相關(guān)的一些技術(shù)細(xì)節(jié)加以探討。

#T#

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

從FrameworkElement繼承

增加一個(gè)Button到它的VisualTree上

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

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

然后將這個(gè)MyElement加入測(cè)試窗口,代碼如下:

 
 
 
  1. Code   
  2.     
  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.   
  10.  Margin="10"/>  
  11.   
  12.  

運(yùn)行后的結(jié)果如下:

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

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

為了將Button真正掛接到MyElement的VisualTree上,還需要額外做一件事情:在VisualTree上為這個(gè)Button分配空間并且指定位置,這個(gè)過程叫做Layout。此過程分兩個(gè)部分:一個(gè)是Measure,另一個(gè)是Arrange。這兩個(gè)過程在FrameworkElement上對(duì)應(yīng)著兩個(gè)方法: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. return availableSize;
  12. }
  13. protected override Size ArrangeOverride(Size finalSize)
  14. {
  15. Rect arrangeRect = new Rect()
  16. {
  17. Width = finalSize.Width,
  18. Height = finalSize.Height
  19. };
  20. if (this.VisualChildrenCount > 0)
  21. {
  22. UIElement child = this.GetVisualChild(0) as UIElement;
  23. Debug.Assert(child != null); // !Assert
  24. child.Arrange(arrangeRect);
  25. }
  26. return finalSize;
  27. }

再次運(yùn)行程序:

目標(biāo)實(shí)現(xiàn)。

由此,我們可以總結(jié)出這個(gè)問題的解決方案如下:

在MyElement的構(gòu)造器中調(diào)用AddVisualChild方法;

重寫VisualChildCount屬性;

重寫GetVisualChild方法;

重寫MeasureOverride方法;

重寫ArrangeOverride方法;

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

1、Panel

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

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

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

AddVisualChild

VisualChildCount

GetVisualChild

2、VisualCollection

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

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


標(biāo)題名稱:詳解WPF中VisualTree增加Visual的處理方法
本文地址:http://m.5511xx.com/article/dpsehih.html