Completed
Last Updated: 28 Aug 2017 10:08 by ADMIN
ADMIN
Hristo
Created on: 25 Aug 2017 13:29
Category: Dock
Type: Bug Report
2
FIX. RadDock - the tool windows are not resized correctly in higher DPI
How to reproduce: try resizing a too window using its splitter

Workaround: create a custom RadDock using special layout strategy
public class MyRadDock : RadDock
{
    public override string ThemeClassName
    {
        get
        {
            return typeof(RadDock).FullName;
        }
    }

    protected override SplitContainerLayoutStrategy CreateLayoutStrategy()
    {
        MySplitContainerLayoutStrategy strategy = null;
        if (this.LayoutStrategyType != null)
        {
            try
            {
                strategy = Activator.CreateInstance(this.LayoutStrategyType) as MySplitContainerLayoutStrategy;
            }
            catch
            {
                strategy = null;
            }
        }

        if (strategy == null)
        {
            strategy = new MySplitContainerLayoutStrategy();
        }

        strategy.RootContainerType = typeof(RadDock);
        return strategy;
    }
}

public class MySplitContainerLayoutStrategy : SplitContainerLayoutStrategy
{
    protected override void Measure()
    {
        SplitContainerLayoutInfo layoutInfo = (SplitContainerLayoutInfo)typeof(SplitContainerLayoutStrategy).GetField("layoutInfo", BindingFlags.Instance | BindingFlags.NonPublic).
            GetValue(this);

        SplitPanel fillPanel = (SplitPanel)typeof(SplitContainerLayoutInfo).GetField("fillPanel", BindingFlags.Instance | BindingFlags.NonPublic).
            GetValue(layoutInfo);

        if (fillPanel == null)
        {
            base.Measure();
        }

        this.MeasureWithFillPanel();

        typeof(SplitContainerLayoutStrategy).GetMethod("ClampMeasuredLength", BindingFlags.Instance | BindingFlags.NonPublic).
            Invoke(this, new object[] { });
    }

    private void MeasureWithFillPanel()
    {
        FieldInfo layoutInfoFi = typeof(SplitContainerLayoutStrategy).GetField("layoutInfo", BindingFlags.Instance | BindingFlags.NonPublic);
        SplitContainerLayoutInfo layoutInfo = (SplitContainerLayoutInfo)layoutInfoFi.GetValue(this);

        int availableLength = (int)typeof(SplitContainerLayoutInfo).GetField("availableLength", BindingFlags.Instance | BindingFlags.NonPublic).
          GetValue(layoutInfo);

        int remaining = availableLength;
        SplitPanel panel;

        //calculate the desired size of all non-fill panels
        int desiredNonFillLength = 0;

        List<SplitPanel> layoutTargets = (List<SplitPanel>)typeof(SplitContainerLayoutInfo).GetField("layoutTargets", BindingFlags.Instance | BindingFlags.NonPublic).
            GetValue(layoutInfo);

        SplitPanel fillPanel = (SplitPanel)typeof(SplitContainerLayoutInfo).GetField("fillPanel", BindingFlags.Instance | BindingFlags.NonPublic).
              GetValue(layoutInfo);

        int count = layoutTargets.Count;
        for (int i = 0; i < count; i++)
        {
            panel = layoutTargets[i];
            if (panel == fillPanel)
            {
                continue;
            }

            desiredNonFillLength += this.GetLength(panel.SizeInfo.AbsoluteSize);
        }

        SplitPanelSizeInfo fillInfo = fillPanel.SizeInfo;

        int totalSplitterLength = (int)typeof(SplitContainerLayoutInfo).GetField("totalSplitterLength", BindingFlags.Instance | BindingFlags.NonPublic).
              GetValue(layoutInfo);
        int layoutableLength = availableLength - totalSplitterLength;
        int correction = 0;

        int totalMinLength = (int)typeof(SplitContainerLayoutInfo).GetField("totalMinLength", BindingFlags.Instance | BindingFlags.NonPublic).
              GetValue(layoutInfo);

        int desiredFillLength = totalMinLength;
        if (desiredNonFillLength + desiredFillLength > layoutableLength)
        {
            correction = (desiredNonFillLength + desiredFillLength) - layoutableLength;
        }

        int remainingCorrection = correction;
        for (int i = 0; i < layoutTargets.Count; i++)
        {
            panel = layoutTargets[i];
            if (panel == fillPanel)
            {
                continue;
            }

            int length = this.GetLength(TelerikDpiHelper.ScaleSize(panel.SizeInfo.AbsoluteSize, new SizeF(1f / panel.SplitPanelElement.DpiScaleFactor.Width, 1f / panel.SplitPanelElement.DpiScaleFactor.Height)));
            if (remainingCorrection > 0 && panel.SizeInfo.SizeMode != SplitPanelSizeMode.Absolute)
            {
                float factor = (float)length / desiredNonFillLength;
                int panelCorrection = Math.Max(1, (int)(factor * correction));
                remainingCorrection -= panelCorrection;
                length -= panelCorrection;
            }

            panel.SizeInfo.MeasuredLength = length;
            int splitterLength = (int)typeof(SplitContainerLayoutInfo).GetField("splitterLength", BindingFlags.Instance | BindingFlags.NonPublic).
             GetValue(layoutInfo);
            remaining -= (panel.SizeInfo.MeasuredLength + splitterLength);
        }
        
        fillPanel.SizeInfo.MeasuredLength = remaining;
    }
}

0 comments