Dirkster99 / AvalonDock

Our own development branch of the well known WPF document docking library
Microsoft Public License
1.39k stars 318 forks source link

Layout bug #473

Open LyonJack opened 6 months ago

LyonJack commented 6 months ago

When there are multiple children with item star, the layout is not allocated according to the proportion

LyonJack commented 6 months ago

LayoutPanelControl.cs func: protected override void OnFixChildrenDockLengths() { if (ActualWidth == 0.0 || ActualHeight == 0.0) return;

#region Setup DockWidth/Height for children

if (_model.Orientation == Orientation.Horizontal)
{
    if (_model.ContainsChildOfType<LayoutDocumentPane, LayoutDocumentPaneGroup>())
    {
        for (var i = 0; i < _model.Children.Count; i++)
        {
            if (_model.Children[i] as ILayoutContainer != null &&
                ((_model.Children[i] as ILayoutContainer).IsOfType<LayoutDocumentPane, LayoutDocumentPaneGroup>() ||
                 (_model.Children[i] as ILayoutContainer).ContainsChildOfType<LayoutDocumentPane, LayoutDocumentPaneGroup>()))
            {
                // Keep set values (from XML for instance)
                if (!(_model.Children[i] as ILayoutPositionableElement).DockWidth.IsStar) (_model.Children[i] as ILayoutPositionableElement).DockWidth = new GridLength(1.0, GridUnitType.Star);
            }
            else if (_model.Children[i] as ILayoutPositionableElement != null && (_model.Children[i] as ILayoutPositionableElement).DockWidth.IsStar)
            {
                var childPositionableModelWidthActualSize = _model.Children[i] as ILayoutPositionableElement as ILayoutPositionableElementWithActualSize;
                var childDockMinWidth = (_model.Children[i] as ILayoutPositionableElement).CalculatedDockMinWidth();
                if (childPositionableModelWidthActualSize.ActualWidth == 0)
                {
                    if (childPositionableModelWidthActualSize.DockWidth.IsStar)
                    {
                        childPositionableModelWidthActualSize.ActualWidth = (ActualWidth - _model.Children.Cast<ILayoutPositionableElement>()
                            .Where(j => j.DockWidth.IsAbsolute)
                            .Select(j => j.DockWidth.Value)
                            .Sum()) * childPositionableModelWidthActualSize.DockWidth.Value / _model.Children.Cast<ILayoutPositionableElement>()
                            .Where(j => j.DockWidth.IsStar)
                            .Select(j => j.DockWidth.Value)
                            .Sum();
                    }
                    else if (childPositionableModelWidthActualSize.DockWidth.IsAbsolute)
                    {
                        childPositionableModelWidthActualSize.ActualWidth = childPositionableModelWidthActualSize.DockWidth.Value;
                    }
                }
                var widthToSet = Math.Max(childPositionableModelWidthActualSize.ActualWidth, childDockMinWidth);

                widthToSet = Math.Min(widthToSet, ActualWidth / 2.0);
                widthToSet = Math.Max(widthToSet, childDockMinWidth);
                (_model.Children[i] as ILayoutPositionableElement).DockWidth = new GridLength(widthToSet, GridUnitType.Pixel);
            }
        }
    }
    else
    {
        for (var i = 0; i < _model.Children.Count; i++)
        {
            var childPositionableModel = _model.Children[i] as ILayoutPositionableElement;
            if (!childPositionableModel.DockWidth.IsStar)
            {
                // Keep set values (from XML for instance)
                if (!childPositionableModel.DockWidth.IsStar) childPositionableModel.DockWidth = new GridLength(1.0, GridUnitType.Star);
            }
        }
    }
}
else // Vertical
{
    if (_model.ContainsChildOfType<LayoutDocumentPane, LayoutDocumentPaneGroup>())
    {
        for (var i = 0; i < _model.Children.Count; i++)
        {
            if (_model.Children[i] is ILayoutContainer childContainerModel &&
                (childContainerModel.IsOfType<LayoutDocumentPane, LayoutDocumentPaneGroup>() ||
                 childContainerModel.ContainsChildOfType<LayoutDocumentPane, LayoutDocumentPaneGroup>()))
            {
                // Keep set values (from XML for instance)
                if (!(_model.Children[i] as ILayoutPositionableElement).DockHeight.IsStar) (_model.Children[i] as ILayoutPositionableElement).DockHeight = new GridLength(1.0, GridUnitType.Star);
            }
            else if (_model.Children[i] as ILayoutPositionableElement != null && (_model.Children[i] as ILayoutPositionableElement).DockHeight.IsStar)
            {
                var childPositionableModelWidthActualSize = _model.Children[i] as ILayoutPositionableElement as ILayoutPositionableElementWithActualSize;
                var childDockMinHeight = (_model.Children[i] as ILayoutPositionableElement).CalculatedDockMinHeight();
                if (childPositionableModelWidthActualSize.ActualHeight == 0)
                {
                    if (childPositionableModelWidthActualSize.DockHeight.IsStar)
                    {
                        childPositionableModelWidthActualSize.ActualHeight = ((ActualHeight - _model.Children.Cast<ILayoutPositionableElement>()
                            .Where(j => j.DockHeight.IsAbsolute)
                            .Select(j => j.DockHeight.Value)
                            .Sum())) * childPositionableModelWidthActualSize.DockHeight.Value / _model.Children.Cast<ILayoutPositionableElement>()
                            .Where(j => j.DockHeight.IsStar)
                            .Select(j => j.DockHeight.Value)
                            .Sum();
                    }
                    else if (childPositionableModelWidthActualSize.DockHeight.IsAbsolute)
                    {
                        childPositionableModelWidthActualSize.ActualHeight = childPositionableModelWidthActualSize.DockHeight.Value;
                    }
                }
                var heightToSet = Math.Max(childPositionableModelWidthActualSize.ActualHeight, childDockMinHeight);
                heightToSet = Math.Min(heightToSet, ActualHeight / 2.0);
                heightToSet = Math.Max(heightToSet, childDockMinHeight);
                (_model.Children[i] as ILayoutPositionableElement).DockHeight = new GridLength(heightToSet, GridUnitType.Pixel);
            }
        }
    }
    else
    {
        for (var i = 0; i < _model.Children.Count; i++)
        {
            var childPositionableModel = _model.Children[i] as ILayoutPositionableElement;
            if (!childPositionableModel.DockHeight.IsStar)
            {
                // Keep set values (from XML for instance)
                if (!childPositionableModel.DockHeight.IsStar) childPositionableModel.DockHeight = new GridLength(1.0, GridUnitType.Star);
            }
        }
    }
}

#endregion Setup DockWidth/Height for children

}