WinForms Panel内自定义ChatMessage控件被过度截断的问题求助
WinForms Panel内自定义ChatMessage控件被过度截断的问题求助
大家好,我遇到一个WinForms布局的棘手问题,想请各位前辈帮忙分析下:
我做了一个WinForms程序,布局结构是Form → TabControl.TabPage → Panel,平时布局都没什么问题,包括在Panel左边缘放置控件时都能正常显示。但不知道是Visual Studio设计器的bug,还是我自定义控件的代码有问题——当我把自己写的ChatMessage用户控件添加到Panel里时,控件总是被截断,只有很小一部分能显示出来。我特意修改了控件的背景色来确认,结果确实是被截断了,不是控件没绘制出来😂
(截图说明:自定义ChatMessage控件仅显示左上角小部分区域,大部分内容被父容器截断)
下面是我的ChatMessage自定义控件完整代码:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Drawing; using System.Drawing.Drawing2D; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace MessengerApp { public partial class ChatMessage : UserControl { string textf = string.Empty; SizeF stringlänge; bool gedreht = false; int num = 0; public ChatMessage(string texte, int nummer) { InitializeComponent(); Size = new Size(500, 500); num = nummer; textf = texte; Graphics g = CreateGraphics(); stringlänge = g.MeasureString(texte, DefaultFont); Size = new Size((int)stringlänge.Width + 73, (int)stringlänge.Height + 33); } private void ChatMessage_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; g.SmoothingMode = SmoothingMode.AntiAlias; SizeF größe = g.MeasureString(textf, DefaultFont); Size endgröße = new Size((int)größe.Width + 120, (int)größe.Height + 83); int f = 0; int y = (int)größe.Width; if (gedreht) { f = 20; y = (int)größe.Width + 73; } // Hauptrechteck der Sprechblase RectangleF rect = new RectangleF(1 + f, 1, größe.Width + 50, größe.Height + 30); float radius = 20f; Size = new Size(y, (int)rect.Height + 3); // Zeiger-Einstellungen bool zeigerLinks = gedreht;// Ändere zu false für rechte Seite PointF zeigerSpitze; PointF zeigerOben; PointF zeigerUnten; if (zeigerLinks) { zeigerSpitze = new PointF(rect.Left - 20, rect.Bottom); zeigerOben = new PointF(rect.Left, zeigerSpitze.Y - 20); zeigerUnten = new PointF(rect.Left, zeigerSpitze.Y); } else { zeigerSpitze = new PointF(rect.Right + 20, rect.Bottom); zeigerOben = new PointF(rect.Right, zeigerSpitze.Y - 20); zeigerUnten = new PointF(rect.Right, zeigerSpitze.Y); } // Erstelle Pfad mit abgerundetem Rechteck + Zeiger GraphicsPath path = new GraphicsPath(); float d = radius * 2; if (zeigerLinks) { // Start oben links path.AddArc(rect.Left, rect.Top, d, d, 180, 90); path.AddLine(rect.Left + radius, rect.Top, rect.Right - radius, rect.Top); path.AddArc(rect.Right - d, rect.Top, d, d, 270, 90); path.AddLine(rect.Right, rect.Top + radius, rect.Right, rect.Bottom - radius); path.AddArc(rect.Right - d, rect.Bottom - d, d, d, 0, 90); PointF control = new PointF(zeigerOben.X, zeigerSpitze.Y - 10); PointF control2 = new PointF(zeigerSpitze.X + 10, zeigerSpitze.Y); PointF control4 = new PointF(zeigerOben.X - 10.01f, zeigerOben.Y + 10.01f); path.AddBezier(zeigerSpitze, control4, control, zeigerOben); // path.AddLine(zeigerSpitze.X, zeigerSpitze.Y, rect.Left, zeigerOben.Y); path.AddLine(rect.Left, zeigerOben.Y - 10, rect.Left, rect.Top + radius); } else { // Start oben links path.AddArc(rect.Left, rect.Top, d, d, 180, 90); path.AddLine(rect.Left + radius, rect.Top, rect.Right - radius, rect.Top); path.AddArc(rect.Right - d, rect.Top, d, d, 270, 90); path.AddLine(rect.Right, rect.Top + radius, rect.Right, rect.Bottom - radius); // path.AddLine(rect.Right - radius, rect.Bottom, rect.Left + radius, rect.Bottom); PointF control = new PointF(zeigerOben.X, zeigerSpitze.Y - 10); PointF control2 = new PointF(zeigerSpitze.X - 10, zeigerSpitze.Y); PointF control4 = new PointF(zeigerOben.X + 0.01f, zeigerOben.Y - 0.01f); path.AddBezier(zeigerOben, control4, control, zeigerSpitze); path.AddLine(rect.Right - radius, rect.Bottom, rect.Left + radius, rect.Bottom); path.AddArc(rect.Left, rect.Bottom - d, d, d, 90, 90); // path.AddLine(zeigerSpitze.X, zeigerSpitze.Y, rect.Left, zeigerOben.Y); // path.AddLine(rect.Left, rect.Bottom - 10, rect.Left, rect.Top + radius); } path.CloseFigure(); // Füllen using (Brush b = new SolidBrush(Color.LightBlue)) { g.FillPath(b, path); } // Umriss using (Pen p = new Pen(Color.DarkBlue, 2)) { g.DrawPath(p, path); } // Text string text = textf; using (Font font = new Font("Segoe UI", 10)) using (Brush tb = new SolidBrush(Color.Black)) { RectangleF textRect = rect; g.DrawString(text, font, tb, textRect, new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center }); } } public int number { get { return num; } } public bool drehen { get { return gedreht; } set { gedreht = value; } } } }
我将控件添加到Panel的代码片段如下(未粘贴完整,关键逻辑是实例化ChatMessage后添加到panel1):
foreach ((int, string, string) strings in ns.GetList) { if (!panel1.Controls.OfType<ChatMessage>...) { // 实例化ChatMessage并添加到panel1的逻辑 var chatMsg = new ChatMessage(strings.Item2, strings.Item1); panel1.Controls.Add(chatMsg); } }
我自己检查了自定义控件的代码:在构造函数和Paint事件里都根据文本长度调整了控件的Size,但还是出现截断的情况。想请教各位:
- 会不会是Panel的AutoScroll或者AutoSize属性没设置对?
- 自定义控件的Size调整逻辑有没有问题?比如在Paint事件里动态改Size会不会导致布局异常?
- 有没有可能是TabPage/Panel的布局模式(比如Dock、Anchor)影响了控件的显示?
麻烦大家帮忙看看,谢谢啦!
内容来源于stack exchange
相关产品推荐
相关产品推荐

