代码改变世界

WP7备注(28)(自适应的Panel自定义UniformStack)

2011-05-02 17:07  血糯米Otomii  阅读(386)  评论(0编辑  收藏  举报
public class UniformStack : Panel
{
public static readonly DependencyProperty OrientationProperty =
DependencyProperty.Register("Orientation",
typeof(Orientation),
typeof(UniformStack),
new PropertyMetadata(Orientation.Vertical, OnOrientationChanged));
public Orientation Orientation
{
set { SetValue(OrientationProperty, value); }
get { return (Orientation)GetValue(OrientationProperty); }
}
static void OnOrientationChanged(DependencyObject obj,
DependencyPropertyChangedEventArgs args)
{
(obj as UniformStack).InvalidateMeasure();
}
…
}

InvalidateMeasure方法的调用使控件重新测量和安排元素的位置

MeasureOverride()重写测量方法

protected override Size MeasureOverride(Size availableSize)
{
if (Children.Count == 0)
return new Size();
Size availableChildSize = new Size();
Size maxChildSize = new Size();
Size compositeSize = new Size();
// Calculate an available size for each child
if (Orientation == Orientation.Horizontal)
availableChildSize = new Size(availableSize.Width / Children.Count,
availableSize.Height);
else
availableChildSize = new Size(availableSize.Width,
availableSize.Height / Children.Count);
// Enumerate the children, and find the widest width and the highest height
foreach (UIElement child in Children)
{
child.Measure(availableChildSize);
maxChildSize.Width = Math.Max(maxChildSize.Width, child.DesiredSize.Width);
maxChildSize.Height = Math.Max(maxChildSize.Height,
child.DesiredSize.Height);
}
// Now determine a composite size that depends on infinite available width or
height
if (Orientation == Orientation.Horizontal)
{
if (Double.IsPositiveInfinity(availableSize.Width))
compositeSize = new Size(maxChildSize.Width * Children.Count,
maxChildSize.Height);
else
compositeSize = new Size(availableSize.Width, maxChildSize.Height);
}
else
{
if (Double.IsPositiveInfinity(availableSize.Height))
compositeSize = new Size(maxChildSize.Width,
maxChildSize.Height * Children.Count);
else
compositeSize = new Size(maxChildSize.Width, availableSize.Height);
}
return compositeSize;
}

重写ArrangeOverride重新安排控件位置

protected override Size ArrangeOverride(Size finalSize)
{
if (Children.Count > 0)
{
Size finalChildSize = new Size();
double x = 0;
double y = 0;
if (Orientation == Orientation.Horizontal)
finalChildSize = new Size(finalSize.Width / Children.Count,
finalSize.Height);
else
finalChildSize = new Size(finalSize.Width,
finalSize.Height / Children.Count);
foreach (UIElement child in Children)
{
child.Arrange(new Rect(new Point(x, y), finalChildSize));
if (Orientation == Orientation.Horizontal)
x += finalChildSize.Width;
else
y += finalChildSize.Height;
}
}
return base.ArrangeOverride(finalSize);
}