SilverLight自定义布局控件
看到葡萄城控件团队里边关于silverlight的布局控件的内部结构和Pro.Silverlight.4布局控件后收益匪浅,自己也顺手参考着例子写了个布局控件。控件类似于Grid,但有一个Count属性,表示一行可以放的控件数量。可以根据自己的需要改变这个属性,来确定一行的显示。
代码
public class UniformPanel : Panel
{
//定义Count属性
public int Count
{
get { return (int)GetValue(CountProperty); }
set { SetValue(CountProperty, value); }
}
public static readonly DependencyProperty CountProperty =
DependencyProperty.Register("Count", typeof(int), typeof(UniformPanel), new PropertyMetadata(new PropertyChangedCallback(CountChanged)));
private double column;
private double row;
//根据Count属性计算总终确定的行数和列数
private void Caculate()
{
double childCount = (double)this.Children.Count;
if (childCount > 0)
{
if (childCount > Count)
{
column = Count;
row = (int)Math.Ceiling(childCount / Count);
}
else if (childCount < Count)
{
column = childCount;
row = 1;
}
}
}
//重写MeasureOverrride方法确定最终需要的大小
protected override Size MeasureOverride(Size availableSize)
{
Caculate();
Size maxSize = new Size(0, 0);
foreach (UIElement item in this.Children)
{
item.Measure(availableSize);
maxSize.Height = Math.Max(item.DesiredSize.Height, maxSize.Height);
maxSize.Width = Math.Max(item.DesiredSize.Width, maxSize.Width);
}
double maxWidth = Math.Max(maxSize.Width * column, availableSize.Width);
double maxHeight = Math.Max(maxSize.Height * row, availableSize.Height);
return new Size(maxWidth, maxHeight);
}
//重写ArrangOverride方法
protected override Size ArrangeOverride(Size finalSize)
{
Refresh(finalSize);
return finalSize;
}
//Count属性改变触发的事件
private static void CountChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
UniformPanel panel = (UniformPanel)sender;
//如果控件没有定义自己的宽高则默认为200*200,否则将报错
if (double.IsNaN(panel.Width) || double.IsNaN(panel.Height))
{
panel.Height = 200;
panel.Width = 200;
}
panel.Refresh(new Size(panel.Width, panel.Height));
}
public void Refresh(Size finalSize)
{
Caculate();
double x = finalSize.Width / column;
double y = finalSize.Height / row;
Rect rect = new Rect(0, 0, x, y);
foreach (UIElement item in this.Children)
{
item.Arrange(rect);
rect.X+=x;
if (rect.X >= x * column)
{
rect.Y += y;
rect.X = 0;
if (rect.Y > y * row)
rect = new Rect(0, 0, 0, 0);
}
}
}
}
设置Count=2效果

设置Count=4效果
源码下载

浙公网安备 33010602011771号