Comment redimensionner des contrôles séparés par un séparateur au-delà de la taille du panneau de conteneur?

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

  •  08-07-2019
  •  | 
  •  

Question

J'ai quelques contrôles utilisateur sur un panneau séparés par des séparateurs. Le panneau contenant est défini sur AutoScroll.

Etant donné que le contrôle Splitter prend en compte la taille de son parent lorsqu'il redimensionne les contrôles qu'il "divise", le redimensionnement des contrôles utilisateur qu'il contient est limité par la taille du panneau.

Je souhaite pouvoir déplacer le séparateur où que se trouve la souris (même au-delà des limites du conteneur / du formulaire) lorsque l'utilisateur le relâche, et que le panneau du conteneur soit redimensionné en conséquence (et affiche les barres de défilement si nécessaire). .

J'ai essayé toutes sortes de combinaisons en l'enveloppant avec différents panneaux, en jouant avec MinSize, etc. C’est le meilleur que j’ai trouvé jusqu’à présent, mais ce n’est pas ce que je veux:

alt text

Quelqu'un a-t-il des idées?

Était-ce utile?

La solution

Vous pouvez définir un crochet de souris lorsque appuyez sur le bouton de la souris et décrochez-le lorsque vous relâchez le bouton. Dans le rappel du crochet, vous pouvez regarder la position de la souris et redimensionner le contrôle comme il convient.

Modifier:

Vous pouvez également utiliser un contrôle spécial que l'utilisateur peut faire glisser pour maintenir la position de défilement dans le coin inférieur droit du conteneur parent. L'utilisateur peut faire glisser le contrôle pour agrandir la zone et, si vous n'utilisez pas les paramètres d'ancrage ou de dock, vous pouvez ajuster manuellement la taille de vos contrôles pour remplir la zone parent.

J'ai mis en place quelque chose comme ceci il y a quelque temps pour un projet que j'ai fait. Je l'ai fait triangulaire et ressembler à la "poignée" sur un ToolStrip . Voici quelques fragments de code du contrôle 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);
}

En ce qui concerne l'implémentation du comportement réel, vous voudrez probablement:

  • Faites défiler jusqu'au porte-parchemin lorsqu'il est déplacé en dehors de la zone visible:
  • Lorsque vous faites défiler l'écran vers le support de défilement, ralentissez-le en appelant Thread.Sleep pendant un court instant (50 ms par exemple).

Autres conseils

Vous devez définir la propriété MinExtra du Splitter sur un grand nombre négatif. Bien que la propriété elle-même ne le permette pas, vous pouvez modifier le champ par réflexion:

typeof(Splitter).GetField("minExtra", Reflection.BindingFlags.Instance | Reflection.BindingFlags.NonPublic).SetValue(mySplitter, -10000);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top