最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

WPF在VisualTree上增加Visual

 更新時間:2022年06月27日 14:02:35   作者:Aaron Lu  
這篇文章介紹了WPF在VisualTree上增加Visual的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

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

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

  • 從FrameworkElement繼承
  • 增加一個Button到它的VisualTree上

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

    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>

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

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

實際上,在上面這個例子中,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;
        }

再次運行程序:

目標實現(xiàn)。

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

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

  • 重寫VisualChildCount屬性;

  • 重寫GetVisualChild方法;

  • 重寫MeasureOverride方法;

  • 重寫ArrangeOverride方法; 

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

1、Panel

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

    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已經(jīng)替我們將如下幾個工作封裝在了UIElementCollection(Panel的Children屬性)中:

  • AddVisualChild

  • VisualChildCount

  • GetVisualChild

2、VisualCollection

另外,在這個過程中,我們還可以使用一個叫做VisualCollection的類來作為所有 Visual Child的容器。這個容器構(gòu)造的時候需要一個Visual類型的Parent,然后在添加、刪除Visual Child的時候,它的相應方法(Add,Remove)就會幫助我們自動調(diào)用Parent的AddVisualChild和RemoveVisualChild方法。如此一來,我們的工作量又減少了。

到此這篇關于WPF在VisualTree上增加Visual的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • C# 讀寫ini文件操作實現(xiàn)

    C# 讀寫ini文件操作實現(xiàn)

    本文主要介紹了C# 讀寫ini文件操作實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2025-01-01
  • C#中如何生成安裝包

    C#中如何生成安裝包

    這篇文章主要介紹了C#中如何生成安裝包問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • C# 利用PdfSharp生成Pdf文件的示例

    C# 利用PdfSharp生成Pdf文件的示例

    這篇文章主要介紹了C# 利用PdfSharp生成Pdf文件的示例,幫助大家更好的理解和學習使用c#,感興趣的朋友可以了解下
    2021-04-04
  • C#實現(xiàn)根據(jù)年份計算生肖屬相的方法

    C#實現(xiàn)根據(jù)年份計算生肖屬相的方法

    這篇文章主要介紹了C#實現(xiàn)根據(jù)年份計算生肖屬相的方法,涉及C#數(shù)組與字符串的操作技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-03-03
  • c#實現(xiàn)從字符串數(shù)組中把數(shù)字的元素找出來

    c#實現(xiàn)從字符串數(shù)組中把數(shù)字的元素找出來

    下面小編就為大家分享一篇c#實現(xiàn)從字符串數(shù)組中把數(shù)字的元素找出來的方法,希望對大家有所幫助。一起跟隨小編過來看看吧
    2017-12-12
  • C#從DataTable獲取數(shù)據(jù)的方法

    C#從DataTable獲取數(shù)據(jù)的方法

    這篇文章主要介紹了C#從DataTable獲取數(shù)據(jù)的方法,涉及C#操作DataTable的相關技巧,需要的朋友可以參考下
    2015-06-06
  • C#實現(xiàn)單位換算器

    C#實現(xiàn)單位換算器

    這篇文章主要為大家詳細介紹了C#實現(xiàn)單位換算器,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • 詳解C#設計模式編程中生成器模式的使用

    詳解C#設計模式編程中生成器模式的使用

    這篇文章主要介紹了詳解C#設計模式編程中生成器模式的使用,生成器模式主張創(chuàng)建對象的過程和對象的表現(xiàn)應該分離開來,需要的朋友可以參考下
    2016-02-02
  • C#中如何執(zhí)行存儲過程方法

    C#中如何執(zhí)行存儲過程方法

    C#中如何執(zhí)行存儲過程方法,需要的朋友可以參考一下
    2013-04-04
  • 實例代碼講解c# 線程(下)

    實例代碼講解c# 線程(下)

    這篇文章主要介紹了c# 線程的的相關資料,文中示例代碼非常細致,對大家的學習有很大幫助,感興趣的朋友可以了解下
    2020-06-06

最新評論

任丘市| 桂林市| 德昌县| 棋牌| 阿拉善右旗| 雷波县| 冕宁县| 延庆县| 区。| 兴业县| 灵川县| 比如县| 德阳市| 湘潭县| 五大连池市| 连云港市| 固阳县| 镇安县| 黄梅县| 登封市| 许昌市| 柳林县| 资兴市| 武城县| 彭阳县| 衢州市| 蓝田县| 游戏| 涟源市| 兰坪| 淳化县| 邳州市| 望奎县| 南岸区| 运城市| 饶河县| 长子县| 阳城县| 太保市| 凤翔县| 安西县|