Page 1 of 1

C# benutzerdefinierte Usercontrol mit autoscroll: Neue Beschriftungen, die aufgrund einer falschen autoscrollPosition -H

Posted: 21 Mar 2025, 10:07
by Anonymous
Ich entwickle ein benutzerdefiniertes Winforms UserControl, das eine Liste von "Etiketten" (als abgerundete Rechtecke mit Text) angezeigt und die Auto-Scrolling unterstützt. Jedes Mal, wenn ein Benutzer auf eine "+" -Staste klickt, wird eine neue Etikett zu einer Liste hinzugefügt und sollte auf der Steuerung angezeigt werden. Die Onpaint -Methode der Steuerung iteriert über die Liste der Beschriftungen, passt die Position jedes Etiketts gemäß dem aktuellen Scroll -Offset (unter Verwendung von autoscrollPosition) an und zeichnet sie dann.

Code: Select all

public class LabelListController : UserControl
{
int stringNumber = 0;
List labels = new List();

public LabelListController()
{
this.DoubleBuffered = true;
this.AutoScroll = true;
this.BackColor = ColorTranslator.FromHtml("#1B1F3B");
this.Dock = DockStyle.Fill;
InitializeButton();
}

private void InitializeButton()
{
Button plusButton = new Button()
{
Text = "+",
BackColor = ColorTranslator.FromHtml("#2B2B2B"),
FlatStyle = FlatStyle.Flat,
Size = new Size(30, 30),
Location = new Point(this.Width - 50, 10),
Anchor = AnchorStyles.Top | AnchorStyles.Right
};
plusButton.FlatAppearance.BorderSize = 0;
this.Controls.Add(plusButton);

plusButton.Click += PlusButton_Click;
}

private void PlusButton_Click(object sender, EventArgs e)
{
this.stringNumber++;
int newY = 20 + (stringNumber - 1) * 80;
labels.Add(new Rectangle(20, newY, 100, 60));
this.AutoScrollMinSize = new Size(0, labels.Count * 80 + 40);
this.Invalidate();
}

protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);

foreach (var rect in labels)
{
int shiftedY = rect.Y - this.AutoScrollPosition.Y;
Rectangle shiftedRect = new Rectangle(rect.X, shiftedY, rect.Width, rect.Height);
if (e.ClipRectangle.IntersectsWith(shiftedRect))
{
DrawLabel(e, new Point(rect.X, shiftedY), rect.Width, rect.Height);
}
}
}

private void DrawLabel(PaintEventArgs e, Point position, int sizeX, int sizeY)
{
int paddingX = 20;
int paddingY = 20;
int posX = position.X + paddingX;
int posY = position.Y + paddingY;

Rectangle rect = new Rectangle(posX, posY, sizeX, sizeY);

float textX = rect.X + rect.Width / 2f;
float textY = rect.Y + rect.Height / 2f;

DrawRoundedRectangle(
e.Graphics,
rect,
15,
ColorTranslator.FromHtml("#2A1E3C"),
Color.White,
0
);

DrawString(e.Graphics, "Sample Text", textX, textY, 12);
}

private void DrawRoundedRectangle(Graphics g, Rectangle bounds, int cornerRadius, Color fillColor, Color borderColor, float borderWidth)
{
using (GraphicsPath path = new GraphicsPath())
{
int diameter = cornerRadius * 2;
path.AddArc(bounds.X, bounds.Y, diameter, diameter, 180, 90);
path.AddArc(bounds.Right - diameter, bounds.Y, diameter, diameter, 270, 90);
path.AddArc(bounds.Right - diameter, bounds.Bottom - diameter, diameter, diameter, 0, 90);
path.AddArc(bounds.X, bounds.Bottom - diameter, diameter, diameter, 90, 90);
path.CloseFigure();

using (SolidBrush brush = new SolidBrush(fillColor))
{
g.FillPath(brush, path);
}

if (borderWidth >  0)
{
using (Pen pen = new Pen(borderColor, borderWidth))
{
pen.Alignment = PenAlignment.Center;
g.DrawPath(pen, path);
}
}
}
}

private void DrawString(Graphics g, string text, float x, float y, int textSize)
{
using (System.Drawing.Font drawFont = new System.Drawing.Font("Arial", textSize, FontStyle.Regular))
using (SolidBrush drawBrush = new SolidBrush(Color.White))
{
StringFormat format = new StringFormat
{
Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Center
};

PointF point = new PointF(x, y);
g.DrawString(text, drawFont, drawBrush, point, format);
}
}
}
Ich habe die Mallogik der Kontrolle des Steuerelements debuggen und bemerkt, dass die Etiketten nach dem Scrollen nicht richtig machten.>