WPF learning path (11) Layout (continued); wpf path
The layout is actually a Slot model. Each parent object is assigned a Slot to the sub-object. The sub-object can freely occupy space in the Slot and is controlled by Margin \ verticalignment \ HorizontalAlignment.
Instance
<Border Background="LightBlue" BorderBrush="Black" BorderThickness="2" CornerRadius="45" Padding="25"> <StackPanel Name="SP1" Background="White"> <TextBlock FontSize="15" HorizontalAlignment="Center" Margin="0,0,0,15" Text="StackPanel1"></TextBlock> <Border BorderThickness="1" BorderBrush="Black"> <Button Margin="5,10,15,20">Normal</Button> </Border> <Border BorderThickness="1" BorderBrush="Black"> <Button Margin="5,10,15,20" HorizontalAlignment="Left"> <Button.LayoutTransform> <RotateTransform Angle="15" /> </Button.LayoutTransform> Left</Button> </Border> <Border BorderThickness="1" BorderBrush="Black"> <Button Margin="5,10,15,20" HorizontalAlignment="Right"> <Button.LayoutTransform> <RotateTransform Angle="45" /> </Button.LayoutTransform> Right</Button> </Border> <Border BorderThickness="1" BorderBrush="Black"> <Button Margin="5,10,15,20" HorizontalAlignment="Center"> <Button.LayoutTransform> <RotateTransform Angle="75" /> </Button.LayoutTransform> Center</Button> </Border> <Border BorderThickness="1" BorderBrush="Black"> <Button Margin="5,10,15,20" > <Button.LayoutTransform> <RotateTransform Angle="15" /> </Button.LayoutTransform> LayoutTransform </Button> </Border> <Border BorderThickness="1" BorderBrush="Black"> <Button Margin="5,10,15,20" > <Button.RenderTransform> <RotateTransform Angle="15" /> </Button.RenderTransform> RenderTransform </Button> </Border> </StackPanel></Border>
Note the differences between LayoutTransform and RenderTransform.
Custom Layout
Determining the optimal space size goes through two phases. 1. measurement. The parent element asks the child element for the expected size to determine its size. 2. layout. The parent element informs the child element of its position.
The specific implementation is as follows:
Protected override Size ArrangeOverride (Size arrangeBounds );
Protected override Size MeasureOverride (Size constraint );
Custom mpmpanel
public class CustomPanel : Panel{ public CustomPanel() : base() { } protected override Size MeasureOverride(Size availableSize) { double maxChildWidth = 0.0; double maxChildHeight = 0.0; foreach (UIElement child in InternalChildren) { child.Measure(availableSize); maxChildWidth = Math.Max(child.DesiredSize.Width, maxChildWidth); maxChildHeight = Math.Max(child.DesiredSize.Height, maxChildHeight); } double idealCircumference = maxChildWidth * InternalChildren.Count; double idealRadius = idealCircumference / (Math.PI * 2) + maxChildHeight; Size desired = new Size(idealRadius * 2, idealRadius * 2); if (!double.IsInfinity(availableSize.Width)) { if (availableSize.Width < desired.Width) desired.Width = availableSize.Width; } if (!double.IsInfinity(availableSize.Height)) { if (availableSize.Height < desired.Height) desired.Height = availableSize.Height; } return desired; } protected override Size ArrangeOverride(Size finalSize) { Rect layoutRect; if (finalSize.Width > finalSize.Height) { layoutRect = new Rect((finalSize.Width - finalSize.Height) / 2, 0, finalSize.Height, finalSize.Height); } else { layoutRect = new Rect((finalSize.Height - finalSize.Width) / 2, 0, finalSize.Width, finalSize.Width); } double angleInc = 360 / InternalChildren.Count; double angle = 0; foreach (UIElement child in InternalChildren) { Point childLocation = new Point(layoutRect.Left + (layoutRect.Width - child.DesiredSize.Width) / 2, layoutRect.Top); child.RenderTransform = new RotateTransform(angle, child.DesiredSize.Width / 2, finalSize.Height / 2 - layoutRect.Top); angle += angleInc; child.Arrange(new Rect(childLocation, child.DesiredSize)); } return finalSize; }}
<Page x:Class="Alex_WPFAPPDemo09.DemoPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:Alex_WPFAPPDemo09" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300" Title="DemoPage"> <Grid Margin="5"> <local:CustomPanel> <Button Content="1" MinWidth="100" /> <Button Content="2" MinWidth="100" /> <Button Content="3" MinWidth="100" /> <Button Content="4" MinWidth="100" /> <Button Content="5" MinWidth="100" /> <Button Content="6" MinWidth="100" /> <Button Content="7" MinWidth="100" /> </local:CustomPanel> </Grid></Page>
To be continue...