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

WPF在VisualTree上增加Visual

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

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

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

  • 從FrameworkElement繼承
  • 增加一個(gè)Button到它的VisualTree上

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

    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 ;
        }
     }

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

<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>

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

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

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

為了將Button真正掛接到MyElement的VisualTree上,還需要額外做一件事情:在VisualTree上為這個(gè)Button分配空間并且指定位置,這個(gè)過(guò)程叫做Layout。此過(guò)程分兩個(gè)部分:一個(gè)是Measure,另一個(gè)是Arrange。這兩個(gè)過(guò)程在FrameworkElement上對(duì)應(yīng)著兩個(gè)方法: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;
        }

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

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

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

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

  • 重寫VisualChildCount屬性;

  • 重寫GetVisualChild方法;

  • 重寫MeasureOverride方法;

  • 重寫ArrangeOverride方法; 

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

1、Panel

還是本文開始提到的問(wèn)題,只不過(guò)要將其中的FrameworkElement換為Panel。除了上面所提到的方法,Panel為我們提供了更加方便的實(shí)現(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)替我們將如下幾個(gè)工作封裝在了UIElementCollection(Panel的Children屬性)中:

  • AddVisualChild

  • VisualChildCount

  • GetVisualChild

2、VisualCollection

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

到此這篇關(guān)于WPF在VisualTree上增加Visual的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

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

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

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

    C#中如何生成安裝包

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

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

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

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

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

    c#實(shí)現(xiàn)從字符串?dāng)?shù)組中把數(shù)字的元素找出來(lái)

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

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

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

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

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

    詳解C#設(shè)計(jì)模式編程中生成器模式的使用

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

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

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

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

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

最新評(píng)論

巫山县| 上饶市| 天津市| 邮箱| 布尔津县| 吉水县| 渑池县| 扬州市| 林芝县| 阳信县| 衡水市| 巴南区| 虞城县| 广丰县| 巢湖市| 大渡口区| 乌鲁木齐市| 侯马市| 五寨县| 高密市| 轮台县| 伽师县| 临夏市| 宜兰市| 宁武县| 商南县| 和田县| 卢氏县| 集安市| 民乐县| 景德镇市| 胶州市| 秦安县| 吉安市| 蓝田县| 壶关县| 梁山县| 马边| 甘南县| 邵阳市| 陆良县|