很长一段时间不想学习WPF了,每次开电脑就停留在网页上。不说废话了。。。。。。。

先来一张截图:

 这是面板布局中的基本步骤,如果要自定义面板的话, 一般选择直接继承自Panel,然后只需重载Messure,Arrange就行。

下面是我的一个示例:

 截图:

  是一个将控件围绕中心排列的自定义面板,图中的按钮围绕中心旋转,可以用在某些需要简单验证条件的场合。

 下面是主要代码:

 

using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Input;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using System.Windows.Controls.Primitives;
using System.Windows.Documents;
using System.Windows.Threading;

namespace xiaohai.CirclePanel
{
class CirclePanel : Panel //面板特征:定时转动,公布两个方法TimerControl1:开始,TimerControl2:停止 ,用于从外部控制定时器。
{
double angleEach;
Size sizeTotal,sizeLargest;
double radius,x1;
Point ptCenter;
double angle = 5;
public static DependencyProperty OrientationProperty;
DispatcherTimer tim;
static CirclePanel()
{
OrientationProperty
= DependencyProperty.Register("Orientation", typeof(Oritension), typeof(CirclePanel), new FrameworkPropertyMetadata(Oritension.ByWidth, FrameworkPropertyMetadataOptions.AffectsRender));


}
public Oritension Orientation
{
set { SetValue(OrientationProperty, value); }
get { return (Oritension)GetValue(OrientationProperty); }
}

protected override Size MeasureOverride(Size availableSize)
{
sizeTotal
= new Size(0, 0);
angleEach
= 360.0 / InternalChildren.Count;
sizeLargest
= new Size(0, 0);
foreach (UIElement ui in InternalChildren)
{
ui.Measure(
new Size(double.PositiveInfinity, double.PositiveInfinity));
sizeLargest.Width
= Math.Max(sizeLargest.Width, ui.DesiredSize.Width);
sizeLargest.Height
= Math.Max(sizeLargest.Height, ui.DesiredSize.Height);

}
x1
= sizeLargest.Width / (2 * Math.Tan(angleEach * Math.PI / 360));
radius
= Math .Sqrt ( Math .Pow ( ( x1 + sizeLargest.Height),2)+Math .Pow (sizeLargest.Width /2,2));
sizeTotal.Width
+= 2 * radius;
sizeTotal.Height
+= 2 * radius;
return sizeTotal;

}
protected override Size ArrangeOverride(Size finalSize)
{
double multi = Math.Min(finalSize .Width /(2*radius) ,finalSize .Height /(2*radius) );
double angle1 = 0;
ptCenter
= new Point(finalSize.Width / 2, finalSize.Height / 2);

foreach (UIElement ui in InternalChildren)
{
ui.RenderTransform
= Transform.Identity;
ui .Arrange (
new Rect( ptCenter .X -sizeLargest .Width *multi /2,ptCenter .Y -(x1+sizeLargest .Height ) *multi ,sizeLargest.Width*multi ,sizeLargest .Height*multi ));
Point pt
= TranslatePoint(ptCenter , ui);
ui.RenderTransform
= new RotateTransform(angle1, pt.X, pt.Y);
angle1
+= angleEach;
}
return finalSize;
}

void transform(object sender,EventArgs e)
{

foreach (UIElement ui in InternalChildren)
{
Point pt
=TranslatePoint (ptCenter ,ui );
ui.RenderTransform
= new RotateTransform(angle , pt.X, pt.Y);
angle
+=angleEach ;
}
angle
+= 5;//为什么设置成小于5的时候就出问题。求解。。。
if (angle == 360) angle = 0;
}
public CirclePanel()
{
tim
= new DispatcherTimer();
tim.Interval
= TimeSpan.FromMilliseconds(50);
tim.Tick
+= transform;
tim.Start();

}
public void TimerControl1()
{
tim.Start();
}
public void TimerControl2()
{
tim.Stop();
}
}
public enum Oritension
{
ByWidth,
ByHeight
}


}

  还可以由控件高度进行排列,上述代码省略了这种选择。其它的扩展在于你的想象。