Как изменить размер элементов управления, разделенных разделителем, за пределы размера их панели контейнера?

StackOverflow https://stackoverflow.com/questions/1817453

  •  08-07-2019
  •  | 
  •  

Вопрос

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

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

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

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

alt text

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

Это было полезно?

Решение

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

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

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

Некоторое время назад я реализовал нечто подобное для своего проекта.Я сделал его треугольным и похожим на "рукоятку" на 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 мс).

Другие советы

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

typeof(Splitter).GetField("minExtra", Reflection.BindingFlags.Instance | Reflection.BindingFlags.NonPublic).SetValue(mySplitter, -10000);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top