你的位置:首页 > ASP.net教程

[ASP.net教程]WPF学习之路(十一)布局(续)


布局实际上是一个Slot模型,其中每个父对象分配给子对象一个Slot,子对象可以自由占用Slot中的空间,通过Margin\VerticalAlignment\HorizontalAlignment控制

 

实例

<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>

 

注意LayoutTransform和RenderTransform的区别

 

 

 

自定义布局

确定空间最佳尺寸经历两个阶段,1.测量,父元素询问子元素期望的尺寸,来确定自身尺寸 2.布置,父元素告知子元素的位置

具体实现为以下两个重载函数

protected override Size ArrangeOverride(Size arrangeBounds);
protected override Size MeasureOverride(Size constraint);

 

自定义CustomPanel

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"   ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"   ="http://schemas.microsoft.com/winfx/2006/xaml"   ="http://schemas.open"    ="http://schemas.microsoft.com/expression/blend/2008"    ="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...