WPF: Why do we need two steps: Measure and arrange?

Source: Internet
Author: User

Directory

  • Measure and arrange Processes
  • Use of existing controls for measure and arrange
  • Custom Controls demonstrate measure and arrange

 

 

Returned directory
Measure and arrange Processes

First, uielement. the Measure parameter is an available space (size object). This space usually represents the available space that the parent control leaves for you to display. Then, the measurecore inside the uielement will be called, this method determines the size of the measureoverride parameter. The specific process is to first determine whether the size and property values are displayed and set. If yes, directly use the set value. This is why if you forcibly set the width and height of a control, it always keeps the set size (of course, if the size of the parent control is exceeded, WPF will decide whether to crop it based on the iscliptobounds attribute ). Of course, if the setting is not displayed, measurecore determines the available size parameter of measureoverride based on the available size and the current control attributes (such as margin.

 

Then, measureoverride is called. This can be rewritten by the quilt control. The returned result only affects the uielement. desiredsize attribute.

This desiredsize is the result of the calculation including margin, and is restricted by three conditions (priority from top to bottom ):

  • Available size parameters passed in measure
  • Display the set property size
  • Size returned by measureoverride

 

Let's make some examples:

<Grid width = "200" Height = "200">

<Textblock margin = "50"> A </textblock>

</GRID>

 

Obviously, the layoutslot size is 200*200. If we set the width and height of the textblock to 300, the desiredsize of the textblock will also be 200*200. Obviously, the available size in measure is the first constraint.

 

If the first limit is passed, the subsequent limit will be applied. For example, if we set the textblock size to 10*10, the desiredsize of the textblock will become 110*100. In this case, desiredsize is the size of the control display settings plus the Margin Size. 10 + 50*2 = 110.

 

If the size of the textblock is not set, desiredsize will add margin to the result of measureoverride. Here, the result is 107.74*115.96.

 

 

The arrange process determines the uielement. rendersize attribute. The entire process is similar to the measure but is different. First, the input arrange parameter is the location and size of the layoutslot, which is a rect object. Then arrangecore works like measurecore to determine the input arrangeoverride size parameter. this parameter is size, which represents the available size to be displayed.

 

The size returned by arrangeoverride affects the rendersize. However, unlike measureoverride, The rendersize affected by arrangeoverride is not limited by the parameters of the arrange method, that is to say, the rendersize will only be restricted by the display setting attribute size and the arrangeoverride return value. The returned results of measureoverride and arrangeoverride must be affected by the attribute size set for display. This is also reasonable. Imagine how crazy it would be if you set the width and height of an element but it may not be displayed according to the specified size.

 

 

Returned directory
Use of existing controls for measure and arrange

Why use the measure and arrange procedures? We have found many answers from the execution of existing controls.

 

Canvas is a coordinate-based control container, so it does not limit the size of sub-containers because of its own size. Look at this Code:

<Canvas width = "30">

<Button width = "300" Height = "50"/>

</Canvas>

 

The vs designer is very powerful in displaying this complex situation:

 

The canvas is only 30 characters in width, but the button must be 300 characters in width, and the canvas should not be limited to the button size. In the measure stage, canvas does not pass the available size of the parent control in measureoverride to the button. Instead, it uses double. positiveinfinity (representing infinity) as the parameter to call the measure method of the button. After the button sets its desiredsize, canvas does not pass in its arrangeoverride parameter during the arrange process. Instead, it uses the desiredsize of the button as the arrange parameter of the button, this satisfies any size requirement of the button.

 

Similar controls include scrollviewer.

 

In addition, the measureoverride of canvas always returns 0*0. That is to say, if you do not directly set the canvas size, its desiredsize will always be 0*0. Therefore, if you put it in stackpanel, it will not be displayed, because stackpanel will only display the control desiredsize based on different directions (the other direction is not limited). Obviously, the desiredsize of 0*0 will make the canvas invisible. If you place the canvas in the grid, the size of the canvas is the size given by the grid, because the grid will hand over the existing size to the sub-member. If you place the canvas in the scrollviewer, canvas will be infinitely large because scrollviewer itself is infinitely large.

You can also rewrite measureoverride to create a canvas with the desiredsize returned to the minimum value. For details, refer to this article: WPF: a canvas with the minimum size.

 

In addition, textblock is always extended in the form of a single line. textblock performs a line feed plan only when the textwrapping attribute is set.

 

These results are the results of the combination of measure and arrange.

 

Of course, in most cases, if you are not writing custom panel controls, you do not need to care too much about measure and arrange (which also makes many people not very familiar with measure and arrange ). At the same time, many built-in types of WPF include measureoverride and arrangeoverride. You can refer to this article:

Measure override and arrangeoverride of built-in types in WPF

 

For example, the execution of the control type is to measure the first visual child. Then we can directly create a type that inherits from control and add a visual to visualchildren without rewriting measureoverride and arrangeoverride. One control can display the custom control of another control:

Class contentbutton: Control

{

Button BTN;

 

Public contentbutton ()

{

BTN = new button () {content = "mgen "};

Base. addvisualchild (BTN );

}

 

Protected override visual getvisualchild (INT index)

{

Return BTN;

}

 

Protected override int visualchildrencount

{

Get

{

Return 1;

}

}

}

 

Put this custom control in stackpanel, and the button behind it will be displayed directly:

 

 

 

Returned directory
Custom Controls demonstrate measure and arrange

The following custom controls demonstrate interesting measure and arrange.

In measureoverride, a total of 50*50 is returned. Then, the control of 100*100 is always returned in arrange:

Class mycontrol: Control

{

Protected override void onrender (drawingcontext)

{

Base. onrender (drawingcontext );

Drawingcontext. drawrectangle (brushes. Red, null, new rect (new point (), rendersize ));

}

 

Protected override size arrangeoverride (size arrangebounds)

{

Base. arrangeoverride (arrangebounds );

Return new size (100,100 );

}

 

Protected override size measureoverride (size constraint)

{

Base. measureoverride (constraint );

Return new size (50, 50 );

}

}

 

In stackpanel, the control is displayed as 100*50. Because horizontal stackpanel is not limited in size, desiredsize is applied, while vertical size is limited, and rendersize is applied.

In a grid or other containers without a limited size, the size is 100*100, and the control is not enlarged or reduced according to the change of available controls, because arrangeoverride does not use the arrangebounds parameter, and always returns the size of 100*100.

 

 

You can also create a vertical stackpanel, but do not try to stretch the horizontal width of the sub-member. The effect is as follows:

 

Code:

Class mypanel: Panel

{

Protected override size measureoverride (size availablesize)

{

VaR retsize = new size ();

Foreach (uielement UI in internalchildren)

{

Ui. Measure (new size (availablesize. Width, availablesize. Height ));

Retsize. height + = UI. desiredsize. height;

Retsize. width = math. Max (retsize. Width, UI. desiredsize. width );

}

Return retsize;

}

 

Protected override size arrangeoverride (size finalsize)

{

VaR next = new point ();

Foreach (uielement UI in internalchildren)

{

Ui. Arrange (New rect (next, UI. desiredsize ));

Next. Y + = UI. rendersize. height;

 

}

Return finalsize;

}

}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.