コード例 #1
0
        protected override Size MeasureOverride(Size availableSize)
        {
            SetupSplitters();
            ChildDefinitiveLenght.Clear();

            if (Children.Count == 0)
            {
                return(base.MeasureOverride(availableSize));
            }

            //if (!IsDocked)
            //    return new Size();

            System.Diagnostics.Debug.Assert(_splitterList.Count == Children.Count / 2, "One and only one splitter must be present between two consecutive childs!");
            bool foundChildWithInfResizeProperty = false;

            foreach (UIElement child in Children)
            {
                if (child is ResizingPanelSplitter)
                {
                    continue;
                }

                if (Orientation == Orientation.Horizontal &&
                    double.IsInfinity(GetResizeWidth(child)))
                {
                    if (child is DocumentPane ||
                        (child is ResizingPanel && DockingManager.IsPanelContainingDocumentPane(child as ResizingPanel)))
                    {
                        if (foundChildWithInfResizeProperty)
                        {
                            Debug.WriteLine("A child with resize width set to infinty has been corrected to 200");
                            SetResizeWidth(child, 200);
                        }

                        foundChildWithInfResizeProperty = true;
                    }
                    else
                    {
                        SetResizeWidth(child, 200);
                    }
                }
                else if (Orientation == Orientation.Vertical &&
                         double.IsInfinity(GetResizeHeight(child)))
                {
                    if (child is DocumentPane ||
                        (child is ResizingPanel && DockingManager.IsPanelContainingDocumentPane(child as ResizingPanel)))
                    {
                        if (foundChildWithInfResizeProperty)
                        {
                            Debug.WriteLine("A child with resize height set to infinty has been corrected to 200");
                            SetResizeHeight(child, 200);
                        }

                        foundChildWithInfResizeProperty = true;
                    }
                    else
                    {
                        SetResizeHeight(child, 200);
                    }
                }
            }

            if (!foundChildWithInfResizeProperty)
            {
                foreach (UIElement child in Children)
                {
                    if (child is ResizingPanelSplitter)
                    {
                        continue;
                    }

                    if (Orientation == Orientation.Horizontal)
                    {
                        if (child is DocumentPane ||
                            (child is ResizingPanel && DockingManager.IsPanelContainingDocumentPane(child as ResizingPanel)))
                        {
                            SetResizeWidth(child, double.PositiveInfinity);
                            foundChildWithInfResizeProperty = true;
                            break;
                        }
                    }
                    else if (Orientation == Orientation.Vertical &&
                             double.IsInfinity(GetResizeHeight(child)))
                    {
                        if (child is DocumentPane ||
                            (child is ResizingPanel && DockingManager.IsPanelContainingDocumentPane(child as ResizingPanel)))
                        {
                            SetResizeHeight(child, double.PositiveInfinity);
                            foundChildWithInfResizeProperty = true;
                            break;
                        }
                    }
                }
            }

            if (!foundChildWithInfResizeProperty)
            {
                if (Children.Count == 1)
                {
                    if (Orientation == Orientation.Horizontal)
                    {
                        SetResizeWidth(Children[0], double.PositiveInfinity);
                    }
                    else
                    {
                        SetResizeHeight(Children[0], double.PositiveInfinity);
                    }
                }
                else if (Children.Count > 2)
                {
                    if (Orientation == Orientation.Horizontal)
                    {
                        SetResizeWidth(Children[2], double.PositiveInfinity);
                    }
                    else
                    {
                        SetResizeHeight(Children[2], double.PositiveInfinity);
                    }
                }
            }



            #region Horizontal orientation
            if (Orientation == Orientation.Horizontal)
            {
                double totSplittersWidth    = 0;
                double totWidth             = 0;
                int    childWithPosInfWidth = 0;

                List <UIElement>      childsOrderedByWidth = new List <UIElement>();
                ResizingPanelSplitter currentSplitter      = null;
                bool prevChildIsVisible = false;

                for (int i = 0; i < Children.Count; i++)
                {
                    UIElement        child         = Children[i];
                    IDockableControl dockableChild = child as IDockableControl;
                    if (dockableChild != null && !dockableChild.IsDocked)
                    {
                        prevChildIsVisible = false;
                        child.Measure(new Size());
                    }
                    else if (child is ResizingPanelSplitter)
                    {
                        if (currentSplitter != null)
                        {
                            child.Measure(new Size());
                        }
                        else if (prevChildIsVisible)
                        {
                            currentSplitter = child as ResizingPanelSplitter;
                        }

                        //if (//(i < Children.Count - 2 && PrevChildIsVisible(i)) ||
                        //    NextChildIsVisible(i) && PrevChildIsVisible(i)
                        //    )
                        //{
                        //    child.Measure(new Size(double.PositiveInfinity, availableSize.Height));
                        //    totSplittersWidth += child.DesiredSize.Width;
                        //}
                        //else
                        //{
                        //    child.Measure(new Size());
                        //}
                    }
                    else
                    {
                        if (currentSplitter != null)
                        {
                            currentSplitter.Measure(new Size(double.PositiveInfinity, availableSize.Height));
                            totSplittersWidth += currentSplitter.DesiredSize.Width;
                            currentSplitter    = null;
                        }

                        prevChildIsVisible = true;
                        double resWidth = (double)child.GetValue(ResizeWidthProperty);

                        if (double.IsPositiveInfinity(resWidth))
                        {
                            childWithPosInfWidth++;
                        }
                        else
                        {
                            totWidth += resWidth;
                            childsOrderedByWidth.Add(child);
                        }
                    }
                }

                if (currentSplitter != null)
                {
                    currentSplitter.Measure(new Size());
                    currentSplitter = null;
                }


                double widthForPosInfChilds = 0;
                double availWidth           = availableSize.Width - totSplittersWidth;
                double shWidth = double.PositiveInfinity;

                if (totWidth > availWidth)
                {
                    childsOrderedByWidth.Sort(delegate(UIElement e1, UIElement e2)
                    {
                        double resWidth1 = (double)e1.GetValue(ResizeWidthProperty);
                        double resWidth2 = (double)e2.GetValue(ResizeWidthProperty);

                        return(resWidth1.CompareTo(resWidth2));
                    });


                    int    count    = childsOrderedByWidth.Count;
                    int    i        = 0;
                    double resWidth = 0;

                    while ((double)childsOrderedByWidth[i].GetValue(ResizeWidthProperty) * (count - i) + resWidth < availWidth)
                    {
                        i++;

                        if (i >= count)
                        {
                            break;
                        }

                        resWidth += (double)childsOrderedByWidth[i - 1].GetValue(ResizeWidthProperty);
                    }

                    shWidth = (availWidth - resWidth) / (count - i);
                    if (shWidth < 0)
                    {
                        shWidth = 0;
                    }
                }
                else
                {
                    if (childWithPosInfWidth > 0)
                    {
                        widthForPosInfChilds = (availWidth - totWidth) / childWithPosInfWidth;
                    }
                    else
                    {
                        widthForPosInfChilds = (availWidth - totWidth) / childsOrderedByWidth.Count;

                        foreach (UIElement child in childsOrderedByWidth)
                        {
                            double resWidth = (double)child.GetValue(ResizeWidthProperty);
                            //double resHeight = (double)child.GetValue(ResizeHeightProperty);

                            child.SetValue(ResizeWidthProperty, resWidth + widthForPosInfChilds);
                        }
                    }
                }



                for (int i = 0; i < Children.Count; i++)
                {
                    UIElement        child         = Children[i];
                    IDockableControl dockableChild = child as IDockableControl;
                    if (dockableChild != null && !dockableChild.IsDocked)
                    {
                        child.Measure(new Size());
                    }
                    else if (!(child is ResizingPanelSplitter))
                    {
                        double resWidth = (double)child.GetValue(ResizeWidthProperty);

                        if (double.IsPositiveInfinity(resWidth))
                        {
                            ChildDefinitiveLenght[child] = widthForPosInfChilds;
                        }
                        else if (shWidth < resWidth)
                        {
                            ChildDefinitiveLenght[child] = shWidth;
                        }
                        else
                        {
                            ChildDefinitiveLenght[child] = resWidth;
                        }

                        child.Measure(new Size(ChildDefinitiveLenght[child], availableSize.Height));
                    }
                }
            }
            #endregion
            #region Vertical orientation
            else //if (Orientation == Orientation.Horizontal)
            {
                double totSplittersHeight    = 0;
                double totHeight             = 0;
                int    childWithPosInfHeight = 0;

                List <UIElement>      childsOrderedByHeight = new List <UIElement>();
                ResizingPanelSplitter currentSplitter       = null;
                bool prevChildIsVisible = false;

                for (int i = 0; i < Children.Count; i++)
                {
                    UIElement        child         = Children[i];
                    IDockableControl dockableChild = child as IDockableControl;

                    if (dockableChild != null && !dockableChild.IsDocked)
                    {
                        prevChildIsVisible = true;
                        child.Measure(new Size());
                    }
                    else if (child is ResizingPanelSplitter)
                    {
                        if (currentSplitter != null)
                        {
                            child.Measure(new Size());
                        }
                        else if (prevChildIsVisible)
                        {
                            currentSplitter = child as ResizingPanelSplitter;
                        }

                        //if ((i < Children.Count - 2 &&
                        //    PrevChildIsVisible(i)) ||
                        //    NextChildIsVisible(i) && PrevChildIsVisible(i)
                        //    )
                        //{
                        //    child.Measure(new Size(availableSize.Width, double.PositiveInfinity));
                        //    totSplittersHeight += child.DesiredSize.Height;
                        //}
                        //else
                        //{
                        //    child.Measure(new Size());
                        //}
                    }
                    else
                    {
                        if (currentSplitter != null)
                        {
                            currentSplitter.Measure(new Size(double.PositiveInfinity, availableSize.Height));
                            totSplittersHeight += currentSplitter.DesiredSize.Height;
                            currentSplitter     = null;
                        }

                        prevChildIsVisible = true;

                        double resHeight = (double)child.GetValue(ResizeHeightProperty);

                        if (double.IsPositiveInfinity(resHeight))
                        {
                            childWithPosInfHeight++;
                        }
                        else
                        {
                            totHeight += resHeight;
                            childsOrderedByHeight.Add(child);
                        }
                    }
                }

                if (currentSplitter != null)
                {
                    currentSplitter.Measure(new Size());
                    currentSplitter = null;
                }

                Debug.Assert(childWithPosInfHeight <= 1);

                double heightForPosInfChilds = 0;
                double availHeight           = availableSize.Height - totSplittersHeight;
                double shHeight = double.PositiveInfinity;

                if (totHeight > availHeight)
                {
                    childsOrderedByHeight.Sort(delegate(UIElement e1, UIElement e2)
                    {
                        double resHeight1 = (double)e1.GetValue(ResizeHeightProperty);
                        double resHeight2 = (double)e2.GetValue(ResizeHeightProperty);

                        return(resHeight1.CompareTo(resHeight2));
                    });

                    int    count     = childsOrderedByHeight.Count;
                    int    i         = 0;
                    double resHeight = 0;

                    while ((double)childsOrderedByHeight[i].GetValue(ResizeHeightProperty) * (count - i) + resHeight < availHeight)
                    {
                        i++;

                        if (i >= count)
                        {
                            break;
                        }

                        resHeight += (double)childsOrderedByHeight[i - 1].GetValue(ResizeHeightProperty);
                    }

                    shHeight = (availHeight - resHeight) / (count - i);
                    if (shHeight < 0)
                    {
                        shHeight = 0;
                    }
                }
                else
                {
                    if (childWithPosInfHeight > 0)
                    {
                        heightForPosInfChilds = (availHeight - totHeight) / childWithPosInfHeight;
                    }
                    else
                    {
                        heightForPosInfChilds = (availHeight - totHeight) / childsOrderedByHeight.Count;

                        foreach (UIElement child in childsOrderedByHeight)
                        {
                            //double resWidth = (double)child.GetValue(ResizeWidthProperty);
                            double resHeight = (double)child.GetValue(ResizeHeightProperty);


                            child.SetValue(ResizeHeightProperty, resHeight + heightForPosInfChilds);
                        }
                    }
                }

                for (int i = 0; i < Children.Count; i++)
                {
                    UIElement        child         = Children[i];
                    IDockableControl dockableChild = child as IDockableControl;
                    if (dockableChild != null && !dockableChild.IsDocked)
                    {
                        child.Measure(new Size());
                    }
                    else if (!(child is ResizingPanelSplitter))
                    {
                        double resHeight = (double)child.GetValue(ResizeHeightProperty);

                        if (double.IsPositiveInfinity(resHeight))
                        {
                            ChildDefinitiveLenght[child] = heightForPosInfChilds;
                        }
                        else if (shHeight < resHeight)
                        {
                            ChildDefinitiveLenght[child] = shHeight;
                        }
                        else
                        {
                            ChildDefinitiveLenght[child] = resHeight;
                        }

                        child.Measure(new Size(availableSize.Width, ChildDefinitiveLenght[child]));
                    }
                }
            }
            #endregion

            //Debug.Assert(ChildDefinitiveLenght.Count > 0);

            return(base.MeasureOverride(availableSize));
        }