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效果
 
源码下载
posted @ 2011-05-13 17:02  JerryT  阅读(689)  评论(0编辑  收藏  举报