WPF 环形布局控件

想要做一个类似于这样的方向控制控件

 

底层的圆都好说,无论是自己动手画还是用图片都能够轻松搞定。

但是那几个方向箭头让我犯愁了。最初尝试做在Canvas画好一个方向箭头,再通过复制,旋转等方式来调整,得到类似于图中的效果。

但是这样画好以后也存在一些问题,比如需要为每个箭头设置点击持续点击的事件就成为一个麻烦;还有可能因为用的是Canvas,导致在别的控件中使用该控件的时候箭头的位置就会发生错位,后来尝试其他布局控件也都不能很好的解决这个问题。

事件的问题后来用RepeatButton来解决了,为其定制Template,设置为箭头的样式,鼠标进入、点击的效果也都在Template里完成了。但是布局问题依旧是个麻烦,就想到自己动手来做一个Panel来满足自己的需要。(之前总是觉得重写那些东西很麻烦,不到万不得已就不想写那些东西)

查看了一些资料,发现其实也不是那么麻烦,继承Panel、重写MeasureOverride,ArrangeOverride方法就OK了,难就难在ArrangeOverride里的方法怎么写,怎样给Children元素定位。

下面我重写的方法,也不知道到底是否完全符合“环形布局控件”的标准,但是至少满足了我目前的应用需求。

   protected override Size MeasureOverride(Size availableSize)
        {
            Size childrenSize = new Size(0, 0);
            foreach (UIElement child in this.Children)
            {
                child.Measure(availableSize);             
                childrenSize.Height = Math.Max(child.DesiredSize.Height, childrenSize.Height);
                childrenSize.Width = Math.Max(child.DesiredSize.Width, childrenSize.Width);
            }
            return childrenSize;
        }

   protected override Size ArrangeOverride(Size finalSize)
        {
            double angle = Math.PI * 2 / this.Children.Count;
            double a = finalSize.Width / 2;
            double b = finalSize.Height / 2;

            foreach (UIElement child in this.Children)
            {
                double childangle = this.Children.IndexOf(child) * angle;

                Point ponit = new Point();
                ponit.X = a * Math.Cos(childangle) + a - child.DesiredSize.Width / 2;
                ponit.Y = b * Math.Sin(childangle) + b - child.DesiredSize.Height / 2;

                Rect rectChild = new Rect(ponit, child.DesiredSize);
                child.Arrange(rectChild);
            }         
            return finalSize;
        }

 

如果大家有更好的方法,欢迎指教!下面是我最后做出的样子~~~

 

posted @ 2010-07-08 09:56  peony007  阅读(2712)  评论(0编辑  收藏