返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >WPF在VisualTree上增加Visual
  • 613
分享到

WPF在VisualTree上增加Visual

2024-04-02 19:04:59 613人浏览 独家记忆
摘要

作为一个WPF控件开发者,我在工作中经常遇到如本文标题所示的问题。其实,这个问题并不是很难,只是在操作上有些繁琐。本文将尝试对这个问题进行解答,并且对相关的一些技术细节加以探讨。 先

作为一个WPF控件开发者,我在工作中经常遇到如本文标题所示的问题。其实,这个问题并不是很难,只是在操作上有些繁琐。本文将尝试对这个问题进行解答,并且对相关的一些技术细节加以探讨。

先从我遇到的一个典型的问题开始吧:写一个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>

运行后的结果如下:

空空如也!嗯,被忽悠了。一阵失落、打击之后,我的好奇心被激发了:这是为什么呢?于是我狂找资料,终于被我发现了:

实际上,在上面这个例子中,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的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持编程网。

--结束END--

本文标题: WPF在VisualTree上增加Visual

本文链接: https://lsjlt.com/news/152769.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • WPF在VisualTree上增加Visual
    作为一个WPF控件开发者,我在工作中经常遇到如本文标题所示的问题。其实,这个问题并不是很难,只是在操作上有些繁琐。本文将尝试对这个问题进行解答,并且对相关的一些技术细节加以探讨。 先...
    99+
    2024-04-02
  • WPF在VisualTree上怎么增加Visual
    本篇内容主要讲解“WPF在VisualTree上怎么增加Visual”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“WPF在VisualTree上怎么增加Visual”吧!代码: &nb...
    99+
    2023-07-02
  • vue如何在元素上增加样式
    这篇文章主要介绍“vue如何在元素上增加样式”,在日常操作中,相信很多人在vue如何在元素上增加样式问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”vue如何在元素上增加样式”的疑惑有所帮助!接下来,请跟着小编...
    99+
    2023-07-05
  • vue怎么在元素上增加样式
    本教程操作环境:windows7系统、vue3版,DELL G3电脑。vue中的添加样式一、使用class样式:类名必须用引号 引起来;1、数组<h1 :class = "['类名1','类名2...
    99+
    2023-05-14
    Vue
  • 详解如何在Ubuntu 16.04上增加Swap分区
    前言 提高服务器响应速度和防止应用程序内存不足错误的最简单方法之一是添加一些交换空间。 在本指南中,我们将介绍如何将交换文件添加到Ubuntu 16.04服务器。 但是,请注意: 尽管swap区通常建议用于使用传统旋转硬...
    99+
    2022-06-04
    swap分区 Ubuntu 16.04 Swap分区
  • 如何给Visual Studio 2010增加背景图片的扩展
    这篇文章主要介绍如何给Visual Studio 2010增加背景图片的扩展,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!前些日子心血来潮去Visual Studio扩展库上淘了一圈,发现了这样一个扩展:http:/...
    99+
    2023-06-17
  • sql怎么在原有表基础上增加一列
    这篇文章主要介绍“sql怎么在原有表基础上增加一列”,在日常操作中,相信很多人在sql怎么在原有表基础上增加一列问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”sql怎么在原有表基础上增加一列”的疑惑有所帮助!...
    99+
    2023-06-20
  • sql怎么在原有的数据上增加数值
    要在原有的数据上增加数值,可以使用UPDATE语句。以下是一个示例:假设有一个名为"table_name"的表,其中有一个名为"co...
    99+
    2023-10-10
    sql
  • 在Linux系统上如何增加swap交换空间
    本篇文章给大家分享的是有关在Linux系统上如何增加swap交换空间,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。在Linux系统中增加服务器swap交换空间大小是为了防止应用...
    99+
    2023-06-28
  • 如何在阿里云服务器上增加内存
    随着云计算的普及,越来越多的企业和个人选择在阿里云上建立服务器来处理大量的数据。然而,如果服务器内存不足,可能会导致运行速度变慢,甚至系统崩溃。那么,如何在阿里云服务器上增加内存呢?本文将为您提供详细的步骤和指导。 在阿里云上增加内存需要您...
    99+
    2023-11-07
    阿里 器上 内存
  • 如何在Visual Studio上开发Node.js程序
    这篇文章主要介绍“如何在Visual Studio上开发Node.js程序”,在日常操作中,相信很多人在如何在Visual Studio上开发Node.js程序问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如...
    99+
    2023-06-17
  • 如何在html增加css
    这篇文章主要为大家展示了“如何在html增加css”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“如何在html增加css”这篇文章吧。 1.行内式 行内式是...
    99+
    2024-04-02
  • Ubuntu上如何增加Swap分区
    这篇文章主要介绍“Ubuntu上如何增加Swap分区”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Ubuntu上如何增加Swap分区”文章能帮助大家解决问题。1.首先来了解一下什么是Swap交换分区...
    99+
    2023-07-04
  • Visual Studio Code在Mac上的常用快捷键
    文件操作: 新建文件:Command + N打开文件:Command + O保存文件:Command + S另存为:Shift + Command + S关闭文件:Command + W关闭所有文件:Shift + Command + W...
    99+
    2023-09-26
    macos vscode ide 编辑器 前端
  • 如何在阿里云服务器上增加磁盘容量
    阿里云服务器是一种强大的云计算服务,为用户提供了可靠、安全和高性能的计算资源。当您需要扩展服务器的存储空间时,可以使用阿里云提供的磁盘扩容功能来增加磁盘容量。本文将详细介绍如何在阿里云服务器上增加磁盘容量,并提供一些示例来帮助您更好地理解...
    99+
    2024-01-16
    阿里 磁盘 器上
  • 怎么在phpmyadmin增加用户
    这篇文章给大家分享的是有关怎么在phpmyadmin增加用户的内容。小编觉得挺实用的,因此分享给大家做个参考。一起跟随小编过来看看吧。如果访问和管理一个数据库系统的人员过多,那么并不是每一个用户都有必要访问...
    99+
    2024-04-02
  • Visual Studio2022史诗级更新,增加多个提高生产力的功能
    Visual Studio 2022发布了17.7x版,这次更新中,增加多个提高生产力的功能以及性能进一步改进。 如果要体验新功能,需要将Visual Studio 2022的版本升级到17.7及以上 下面我们看看新增的功能以及改进的功能!...
    99+
    2023-08-30
    visual studio 文件比较
  • Oracle 11g rac 安装后在asm上增加control file文件副本
    Oracle 11g rac在建库的时候使用了ASM存储,然而rac在建库时默认只在asm上面创建了一个控制文件,如果想多加几个控制文件, 就需要通过手工来添加了,很多人可能会忽略这个细节,但是我们还是希望...
    99+
    2024-04-02
  • 如何增加phpmyadmin导入文件上限
    小编给大家分享一下如何增加phpmyadmin导入文件上限,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!1、首先我们要找到php的配置文件php.ini文件,然后按下Ctrl+F,搜索po...
    99+
    2024-04-02
  • 如何在phpmyadmin里增加字段
    小编给大家分享一下如何在phpmyadmin里增加字段,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!1、打开phpMyAdmin应用软件,在登录页面输入数据库名和登录密码,然后点击执行。2...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作