zoukankan      html  css  js  c++  java
  • 【转】【WPF】WPF中MeasureOverride ArrangeOverride 的理解

    1. Measure Arrange这两个方法是UIElement的方法

        MeasureOverride ArrangeOverride这两个方法是FrameworkElement的方法,FrameworkElement是UIElement的子类

        MeasureOverride传入父容器分配的可用空间,返回该容器根据其子元素大小计算确定的在布局过程中所需的大小。

        ArrangeOverride传入父容易最终分配的控件大小,返回使用的实际大小

    2. MeasureOverride 用于计算本身及其子控件的大小

        ArrangeOverride用于布局本身及其子控件的位置和大小

    3. WPF布局系统大概分为两步:Measure和Arrange

        Measure方法自顶而下,递归调用各子控件的Measure方法,Measure方法会把该控件所需的大小控件存在desired size属性中,控件根据各子控件的desired size 属性确定自身空间大小,并返回自己的desired size 

       Arrange方法发生在Measure中,传入Measure方法计算到的大小,利用控件的位置设置分配子控件的位置

    简单来说,这两个方法一个管大小,一个管布局,都需要调用子类的Measure和Arrage

    public class DiagnolPanel:Panel
        {
            protected override Size MeasureOverride(Size availableSize)
            {
                var mySize = new Size();
    
                foreach (UIElement child in this.InternalChildren)
                {
                    child.Measure(availableSize);
                    mySize.Width += child.DesiredSize.Width;
                    mySize.Height += child.DesiredSize.Height;
                }
    
                return mySize;
            }    
    
            protected override Size ArrangeOverride(Size finalSize)
            {
                var location = new Point();
    
                int childNumber = 0;
                int middleChild = GetTheMiddleChild(this.InternalChildren.Count);
    
                foreach (UIElement child in this.InternalChildren)
                {
                   
                    if (childNumber < middleChild)
                    {
                        child.Arrange(new Rect(location, child.DesiredSize));
                        location.X += child.DesiredSize.Width;
                        location.Y += child.DesiredSize.Height;
                    }
                    else
                    {
                        //The x location will always keep increasing, there is no need to take care of it
                        location.X = GetXLocationAfterMiddleChild(childNumber);
    
                        //If the UIElements are odd in number
                        if (this.InternalChildren.Count % 2 != 0)
                        { 
                            //We need to get the Y location of the child before middle location, 
                            //to have the same Y location for the child after middle child                      
                            int relativeChildBeforeMiddle = middleChild - (childNumber - middleChild);
                            location.Y = GetYLocationAfterMiddleChild(relativeChildBeforeMiddle);
                        }
                        else
                        {
                           ///TODO: Do the design for the even number of children
                        }
    
                        child.Arrange(new Rect(location, child.DesiredSize));
                    }
    
                    childNumber++;
                }
    
                return finalSize;
            }
    
            private double GetXLocationAfterMiddleChild(int childNUmber)
            {
                double xLocation = 0;
                for (int i = 0; i < childNUmber; i++)
                {
                    xLocation += this.InternalChildren[i].DesiredSize.Width;
                }
    
                return xLocation;
            }
    
            private double GetYLocationAfterMiddleChild(int relativeChildNumber)
            {            
                UIElement correspondingChild = this.InternalChildren[relativeChildNumber - 2];
                Point pointCoordinates = 
                correspondingChild.TransformToAncestor((Visual)this.Parent).Transform(new Point(0, 0));
    
                return pointCoordinates.Y;
            }
    
            private int GetTheMiddleChild(int count)
            {
                int middleChild;
                if (count % 2 == 0)
                {
                    middleChild = count / 2;
                }
                else
                {
                    middleChild = (count / 2) + 1;
                }
    
                return middleChild;
            }
        }
    }
    <local:DiagnolPanel>
            <Button BorderBrush="Black" Background="Red" Content="0" Width="40"></Button>
            <Button BorderBrush="Black" Background="Red" Content="1" Width="40"></Button>
    
            <Button BorderBrush="Black" Background="Red" Content="2" Width="40"></Button>
            <Button BorderBrush="Black" Background="Red" Content="3" Width="40"></Button>
    
            <Button BorderBrush="Black" Background="Red" Content="4" Width="40"></Button>
    
            <Button BorderBrush="Black" Background="Red" Content="5" Width="40"></Button>
    
            <Button BorderBrush="Black" Background="Red" Content="6" Width="40"></Button>
            <Button BorderBrush="Black" Background="Red" Content="7" Width="40"></Button>
    
            <Button BorderBrush="Black" Background="Red" Content="8" Width="40"></Button>
    
        </local:DiagnolPanel>

    原文地址:http://www.mamicode.com/info-detail-1730861.html

        https://www.codeproject.com/Articles/1034445/Understanding-MeasureOverride-and-ArrangeOverride

  • 相关阅读:
    java 输出质数
    各大OJ
    使用css让图片居中
    poj 1250 Tanning Salon
    Struts2 中整合DWR3实现文件上传
    C语言I博客作业02
    The first essay.
    tar命令
    wBox Demo
    缓存记录
  • 原文地址:https://www.cnblogs.com/mqxs/p/9562448.html
Copyright © 2011-2022 走看看