如何将由分隔符分隔的控件调整为超出其容器面板大小?

发布于 2024-08-12 19:04:25 字数 385 浏览 8 评论 0原文

我在面板上有一些由分离器分隔的用户控件。 包含面板设置为自动滚动。

由于 Splitter 控件在调整其“分割”的控件大小时会考虑其父控件的大小,因此其中的 UserControls 的大小调整受到面板大小的限制。

我希望能够在用户释放鼠标时将拆分器向下移动到鼠标所在的位置(甚至超出容器/表单的边界),并相应地调整容器面板的大小(并在必要时显示滚动条)。

我尝试过各种组合,用不同的面板包裹它,使用 MinSize 等。 这是迄今为止我想到的最好的,但这不是我想要的:

alt text

有人有什么想法吗?

I've got a few UserControls on a panel separated by splitters.
The containing panel is set to AutoScroll.

Since the Splitter control takes its parent's size into consideration when it resizes the controls it 'splits', the resizing of the UserControls inside it is limited by the panel's size.

I want to be able to move the splitter down to wherever the mouse was (even beyond the bounds of the container/form) when the user release it, and have the container panel resize accordingly (and show the scrollbars if necessary) .

I've tried all sorts of combinations with wrapping it with different panels, playing with the MinSize etc..
This is the best I came up with so far, but it's not what I want:

alt text

Does anyone have any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

爱你不解释 2024-08-19 19:04:25

您需要将 SplitterMinExtra 属性设置为一个较大的负数。虽然属性本身不允许这样做,但您可以通过反射更改该字段:

typeof(Splitter).GetField("minExtra", Reflection.BindingFlags.Instance | Reflection.BindingFlags.NonPublic).SetValue(mySplitter, -10000);

You need to set the MinExtra property of the Splitter to a large negative number. While the property itself doesn't allow this you could alter the field through reflection:

typeof(Splitter).GetField("minExtra", Reflection.BindingFlags.Instance | Reflection.BindingFlags.NonPublic).SetValue(mySplitter, -10000);
话少情深 2024-08-19 19:04:25

您可以在鼠标按钮按下时设置鼠标挂钩被按下并在释放鼠标按钮时将其解除挂钩。在钩子回调中,您可以观察鼠标位置并根据需要调整控件的大小。

编辑:

您可以使用一个特殊的控件,用户可以拖动该控件来将滚动位置固定在父容器的右下角。用户可以拖动控件以使区域更大,如果您不使用锚点或停靠设置,则可以手动调整控件的大小以填充父区域。

我不久前为我所做的一个项目实现了类似的东西。我将其做成三角形,看起来类似于 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 毫秒)来减慢它的速度。

You could set a mouse hook when the mouse button is pressed and unhook it when the mouse button is released. In the hook callback, you can watch the mouse position and resize the control as appropriate.

Edit:

You could instead use a special control which the user can drag to hold the scroll position in the bottom right-hand corner of the parent container. The user could drag the control to make the area bigger and, if you are not using anchor or dock settings, you can manually adjust the size of your controls to fill the parent area.

I implemented something like this a while back for a project I did. I made it triangular and look like similar to the "grip" on a ToolStrip. Here's some code fragments from the ScrollHolder control:

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);
}

As far as the actual behavior implementation goes, you will probably want to:

  • Scroll to the scroll holder when it is moved outside the visible area:
  • When scrolling to the scroll holder, slow it down by calling Thread.Sleep for a short time (such as 50 ms).
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文