Custom WPF panel
Zhou yinhui
WPF has many layout panels, such as grid and stackpanel, which makes our interface layout more flexible, but these panels may not fully meet your needs, in this case, you need to customize the Panel to meet your layout requirements.
1. How is the panel layout implemented?
The WPF layout engine uses a recursive method to implement the layout of controls and their child controls. The general process is as follows: to implement the layout of control, first, implement the sub-controls A1, A2, a3... to achieve the A1 layout, you must implement the A11, A12, a13... after the child control layout is complete, the layout of the parent control is completed, and then recursively goes back. After recursion ends, the layout is complete.
The final size and position of the control are determined by the Control and the parent control. The parent control gives the child control a layout space within its capabilities, the child control returns an expected value to the parent control. The parent control finally allocates a certain amount of space to the Child control based on its own space size and the expected value of the Child control and returns its own size. this process is completed by overwriting the Panel's measureoverride and arrangeoverride methods.
2, size measureoverride (size availablesize) Method
This method evaluates the space required by the layout control.
Refer to the following Code : Protected Override Size measureoverride (size availablesize)
{
Size childrensize = New Size ( 0 , 0 );
Foreach (Uielement child In This . Children)
{< br> child. measure ( New size (double. positiveinfinity, double. positiveinfinity);
childrensize. width += child. desiredsize. width;
childrensize. height += child. desiredsize. height;
}
Return Childrensize;
}
In the measureoverride phase, we call the measure (size sz) method for each child in the Panel. The function of this method is that the parent control tells the child control the expected space to be allocated to the child control, after the measure method is called for child, the child control will send a response to the parent control internally to tell the parent control the expected size, the expected value of the Child control is stored in its child. in desiredsize. if the positive infinity (new size (double. positiveinfinity, double. positiveinfinity), it is equivalent to the parent Control saying to the Child control, "although you need the size, if you can, the world can give it to you ".
The availablesize parameter in the measureoverrice method is the value that is passed in when its parent control (the Panel control you wrote later in actual use) calls the measure method (minus some boundary values, for example, to remove margin)
The returned value of the measureoverride method is the expected value that it tells its parent control, that is, the value of desiredsize after the parent control (the Panel control you wrote is used in actual use later) calls the measure method to it.
Note: As a parent control, you can easily meet the needs of child controls (though not necessarily ), therefore, you can pass in a positive infinity size when calling the measure method on the Child control. However, as a child control, you cannot greedy the parent Control for positive infinity space, therefore, we cannot regard positive infinity as the return value of the measureoverride method, you cannot directly use the availablesize parameter of this method as the return value (because your parent control may pass positive infinity as this parameter to you)
3, size arrangeoverride (size finalsize) Method
This method is used to provide layout space for the Panel sub-control, that is, to arrange the sub-control and return its own size.
Refer to the following code: Protected Override Size arrangeoverride (size finalsize)
{
Point childpos = New Point ( 0 , 0 );
Foreach (Uielement child In This . Children)
{
Child. Arrange (NewRect (childpos,NewSize (child. desiredsize. Width, finalsize. Height )));
Childpos. x+ =Child. rendersize. width;
}
Return Finalsize;
}
This method calls the arrange method for each child. The rect structure passed in the arrange method tells the child control that it is arranged in that space for layout, then, the child elements are placed based on the space they get and their alignment attributes (xxxalignment). After the child elements are placed, the size of the Child control is determined, the value is stored in the rendersize of the sub-control (that is, actualwidth and actualheight ).
The control itself can also determine its own size based on the actual space occupied by the sub-control, or you can directly return the finalsize parameter (that is, the finalsize parameter in the arrangeoverride method) as its final size.
The finalsize parameter in the arrangeoverride method is the size of the rect passed in to the control when calling the arrange method. It is the parent control of the control (the Panel control you have written will be used in the future, just as this control calls the arrange method for its child controls.
Note: The child arrange method only provides a space for the Child control to be placed in this space. The space does not determine the specific position and size of the Child control, which depends on other attributes of the Child control, for example, horizontalalignment and verticalignment. during arrange, alignment is automatically performed.
Is a custom panel mystackpanel, which has two more directions than the built-in stackpanel of WPF ("from right to left" and "from bottom to top ")
Download demo