Как изменить размеры элементов управления, разделенных разделителем, за пределы размера панели контейнера? - PullRequest
2 голосов
/ 30 ноября 2009

У меня есть несколько пользовательских элементов управления на панели, разделенных разделителями. Содержащая панель установлена ​​на AutoScroll.

Поскольку элемент управления Splitter учитывает размер его родителя при изменении размера элементов управления, которые он «разделяет», изменение размера элементов UserControls внутри него ограничено размером панели.

Я хочу иметь возможность перемещать сплиттер туда, где находилась мышь (даже за пределами контейнера / формы), когда пользователь отпускает ее, и соответственно изменять размер панели контейнера (и, если необходимо, показывать полосы прокрутки) .

Я пробовал всевозможные комбинации, оборачивая их разными панелями, играя с MinSize и т.д .. Это лучшее, что я придумал до сих пор, но это не то, что я хочу:

alt text

У кого-нибудь есть идеи?

Ответы [ 2 ]

2 голосов
/ 15 мая 2018

Вам необходимо установить для свойства MinExtra Splitter большое отрицательное число. Хотя само свойство не позволяет этого, вы можете изменить поле с помощью отражения:

typeof(Splitter).GetField("minExtra", Reflection.BindingFlags.Instance | Reflection.BindingFlags.NonPublic).SetValue(mySplitter, -10000);
2 голосов
/ 30 ноября 2009

Вы можете установить крючок мыши , когда кнопка мыши нажата, и отцепить его, когда кнопка мыши отпущена. В обратном вызове ловушки вы можете наблюдать за положением мыши и соответствующим образом изменять размеры элемента управления.

Редактировать:

Вместо этого вы можете использовать специальный элемент управления, который пользователь может перетаскивать, чтобы удерживать позицию прокрутки в нижнем правом углу родительского контейнера. Пользователь может перетащить элемент управления, чтобы увеличить область, и, если вы не используете настройки привязки или дока, вы можете вручную настроить размер элементов управления, чтобы заполнить родительскую область.

Некоторое время назад я реализовал нечто подобное для проекта, который я сделал. Я сделал его треугольным и похож на «захват» на ToolStrip. Вот некоторые фрагменты кода из элемента управления ScrollHolder:

public ScrollHolder()
{
    this.Size = new Size(21, 21);
    this.BackColor = SystemColors.Control;
}

protected override void OnPaint(PaintEventArgs e)
{
    Point bottomLeft = new Point(0, this.Height);
    Point topRight = new Point(this.Width, 0);
    Pen controlDark = SystemPens.ControlDark;
    Pen controlLightLight = SystemPens.ControlLightLight;
    Pen controlDark2Px = new Pen(SystemColors.ControlDark, 2);
    Point bottomRight = new Point(this.Width, this.Height);
    e.Graphics.DrawLine(
        controlLightLight, 
        bottomLeft.X, 
        bottomLeft.Y - 2, 
        bottomRight.X, 
        bottomRight.Y - 2);
    e.Graphics.DrawLine(controlDark, bottomLeft, topRight);
    e.Graphics.DrawLine(
        controlLightLight, 
        bottomLeft.X + 1, 
        bottomLeft.Y, 
        topRight.X, 
        topRight.Y + 1);
    e.Graphics.DrawLine(controlDark2Px, bottomLeft, bottomRight);
    e.Graphics.DrawLine(controlDark2Px, bottomRight, topRight);
    int xNumberOfGripDots = this.Width / 4;
    for (int x = 1; x < xNumberOfGripDots; x++)
    {
        for (int y = 1; y < 5 - x; y++)
        {
            DrawGripDot(e.Graphics, new Point(
                this.Width - (y * 4), this.Height - (x * 4) - 1));
        }
    }
}

private static void DrawGripDot(Graphics g, Point location)
{
    g.FillRectangle(
        SystemBrushes.ControlLightLight, location.X + 1, location.Y + 1, 2, 2);
    g.FillRectangle(SystemBrushes.ControlDark, location.X, location.Y, 2, 2);
}

protected override void OnResize(EventArgs e)
{
    this.SetRegion();
    base.OnResize(e);
}

private void SetRegion()
{
    GraphicsPath path = new GraphicsPath();
    path.AddPolygon(new Point[] 
    { 
        new Point(this.Width, 0), 
        new Point(this.Width, this.Height),
        new Point(0, this.Height) 
    });
    this.Region = new Region(path);
}

Что касается фактической реализации поведения, вы, вероятно, захотите:

  • Прокрутите до держателя прокрутки, когда он перемещается за пределы видимой области:
  • При прокрутке до держателя прокрутки замедлите его, вызвав Thread.Sleep на короткое время (например, 50 мс).
...