很长一段时间不想学习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
}
}
还可以由控件高度进行排列,上述代码省略了这种选择。其它的扩展在于你的想象。
浙公网安备 33010602011771号