WPF在VisualTree上怎么增加Visual
本篇內容主要講解“WPF在VisualTree上怎么增加Visual”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“WPF在VisualTree上怎么增加Visual”吧!
代碼:
????class?MyElement?:?FrameworkElement ????{ ????????private?Button?_button?=?new?Button()?{?Content?=?"I'm?a?Button!"};???????? ????????public?MyElement() ????????{ ????????????this.AssembleVisualChildren(); ????????} ????????private?void?AssembleVisualChildren() ????????{ ????????????this.AddVisualChild(this._button); ????????} ????????protected?override?int?VisualChildrenCount ????????{ ????????????get ????????????{ ????????????????return?1; ????????????} ????????} ????????protected?override?Visual?GetVisualChild(int?index) ????????{???????????? ????????????return?this._button?; ????????} ?????}
然后將這個MyElement加入測試窗口,代碼如下:
<Window? ????x:Class="AddVisualChildTest.Window1" ????xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" ????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" ????xmlns:loc="clr-namespace:AddVisualChildTest" ????WindowStartupLocation="CenterScreen" ????Title="Window1"?Height="300"?Width="300"> ????<Grid> ????????<loc:MyElement?Margin="10"/> ????</Grid> </Window>
運行后的結果如下:
空空如也!嗯,被忽悠了。一陣失落、打擊之后,我的好奇心被激發了:這是為什么呢?于是我狂找資料,終于被我發現了:
實際上,在上面這個例子中,AddVisualChild這個方法只是在MyElement和Button之間建立起了一種VisualTree上的父子關系,但是并沒有將Button掛接到MyElement的VisualTree上,所以最終我們沒有在屏幕上看到這個Button。
為了將Button真正掛接到MyElement的VisualTree上,還需要額外做一件事情:在VisualTree上為這個Button分配空間并且指定位置,這個過程叫做Layout。此過程分兩個部分:一個是Measure,另一個是Arrange。這兩個過程在FrameworkElement上對應著兩個方法:MeasureOverride和ArrangeOverride方法。具體做法如下:
????????protected?override?Size?MeasureOverride(Size?availableSize) ????????{ ????????????if?(this.VisualChildrenCount?>?0) ????????????{ ????????????????UIElement?child?=?this.GetVisualChild(0)?as?UIElement; ????????????????Debug.Assert(child?!=?null);?//?!Assert ????????????????child.Measure(availableSize); ????????????????return?child.DesiredSize; ????????????} ????????????return?availableSize; ????????} ????????protected?override?Size?ArrangeOverride(Size?finalSize) ????????{ ????????????Rect?arrangeRect?=?new?Rect() ????????????{ ????????????????Width?=?finalSize.Width, ????????????????Height?=?finalSize.Height ????????????}; ????????????if?(this.VisualChildrenCount?>?0) ????????????{ ????????????????UIElement?child?=?this.GetVisualChild(0)?as?UIElement; ????????????????Debug.Assert(child?!=?null);?//?!Assert ????????????????child.Arrange(arrangeRect); ????????????} ????????????return?finalSize; ????????}
再次運行程序:
目標實現。
由此,我們可以總結出這個問題的解決方案如下:
在MyElement的構造器中調用AddVisualChild方法;
重寫VisualChildCount屬性;
重寫GetVisualChild方法;
重寫MeasureOverride方法;
重寫ArrangeOverride方法;?
另外,WPF在此問題的解決上也為開發者提供了一些必要的幫助。就我所知的,有如下幾個內容:
1、Panel
還是本文開始提到的問題,只不過要將其中的FrameworkElement換為Panel。除了上面所提到的方法,Panel為我們提供了更加方便的實現方式。代碼如下:
????class?MyElement?:?Panel ????{ ????????private?Button?_button?=?new?Button()?{?Content?=?"I'm?a?Button!"?}; ????????public?MyElement() ????????{ ????????????this.Children.Add(_button); ????????} ????????protected?override?Size?MeasureOverride(Size?availableSize) ????????{ ????????????if?(this.VisualChildrenCount?>?0) ????????????{ ????????????????UIElement?child?=?this.GetVisualChild(0)?as?UIElement; ????????????????Debug.Assert(child?!=?null);?//?!Assert ????????????????child.Measure(availableSize); ????????????????return?child.DesiredSize; ????????????} ????????????return?availableSize; ????????} ????????protected?override?Size?ArrangeOverride(Size?finalSize) ????????{ ????????????Rect?arrangeRect?=?new?Rect() ????????????{ ????????????????Width?=?finalSize.Width, ????????????????Height?=?finalSize.Height ????????????}; ????????????if?(this.VisualChildrenCount?>?0) ????????????{ ????????????????UIElement?child?=?this.GetVisualChild(0)?as?UIElement; ????????????????Debug.Assert(child?!=?null);?//?!Assert ????????????????child.Arrange(arrangeRect); ????????????} ????????????return?finalSize; ????????} ????}
之所以能這樣做的原因是Panel已經替我們將如下幾個工作封裝在了UIElementCollection(Panel的Children屬性)中:
AddVisualChild
VisualChildCount
GetVisualChild
2、VisualCollection
另外,在這個過程中,我們還可以使用一個叫做VisualCollection的類來作為所有 Visual Child的容器。這個容器構造的時候需要一個Visual類型的Parent,然后在添加、刪除Visual Child的時候,它的相應方法(Add,Remove)就會幫助我們自動調用Parent的AddVisualChild和RemoveVisualChild方法。如此一來,我們的工作量又減少了。
到此,相信大家對“WPF在VisualTree上怎么增加Visual”有了更深的了解,不妨來實際操作一番吧!這里是蝸牛博客網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:niceseo99@gmail.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。
評論