Custom User Control Does not Auto Size

Denis Morgan 20 Reputation points
2023-10-11T18:23:54.6433333+00:00

I am trying to create a chat application using C# and have hit a snag on how to create chat bubble that is outgoing and incoming message. My problem is how to auto resize the chat bubble based on the text on the custom Usercontrol. Here I have created a Created a custom UserControl and have added a label and set autosize to false for both Usercontrol and the label. usercontrol background is transparent and the label docked to the right. My main problem is the bubble size does not automatically size according to the text content passed. The height of the bubble remain constants. Here is my Sender Bubble and how am adding it to Panel in another form.

public partial class SenderBubble : UserControl
    {
        public SenderBubble()
        {
            InitializeComponent();
            label1.AutoSize = false; // Set AutoSize to false
            this.AutoSize = false;



        }
        private void ChangeLabelSize()
        {
          
            SizeF size = label1.CreateGraphics().MeasureString(label1.Text, label1.Font);
            label1.MaximumSize = new Size(this.Width, 0);

            label1.Width = this.Width;
            this.MinimumSize = new Size(0, 0);
            this.Height = (int)size.Height;
            this.AutoSize = false;
            Console.WriteLine("Height:" + size.Height);//height of text is not changing*/
            /**
             log output
             Height:20
             Height:20
             */
        }

        public int LabelHeight
        {
            get
            {
                return this.Height = label1.Height;
            }
        }

        [Editor("System.ComponentModel.Design.MultilineStringEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
        public string Body
        {
            get
            {
                return label1.Text;
            }
            set
            {
                label1.Text = value;
                ChangeLabelSize();
            }
        }


     
       //to add border radius
        protected override void OnPaint(PaintEventArgs e)
        {

           GraphicsPath path = RoundedRectangle.Create(label1.ClientRectangle, 8, RoundedRectangle.RectangleCorners.All);
            label1.Region = new Region(path);

            base.OnPaint(e);
        }

      



    }
    
    //this is how am calling / adding the sender bubble.
    int basey=bublePanel.Location.Y;
       private void HandleUserChats(String message)
        {

            SenderBubble bubble = new SenderBubble();     
            bubble.Time = DateTime.Now.ToString("HH:mm");
            bubble.TimeColor = Color.Black;
            bubble.Body = message;
            bubble.Top = basey;
            bublePanel.Controls.Add(bubble);//bublePanel is A Panel which have set autoscroll=true
            int width = bublePanel.ClientSize.Width - bubble.Width;
           
            bubble.Left = width;
            basey += bubble.LabelHeight;

            bublePanel.ScrollControlIntoView(bubble);
            txt_msg_box.Clear();
            txt_msg_box.Focus();





        }
Developer technologies | C#
Developer technologies | C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
0 comments No comments
{count} votes

Answer accepted by question author
  1. KOZ6.0 6,735 Reputation points
    2023-10-15T20:14:48.7366667+00:00

    Comment is too long so I'll post a new answer. Paste the TextBox and Label into the Form and see if MeasureClientSize works.

    using System;
    using System.Drawing;
    using System.Windows.Forms;
    
    public partial class Form1 : Form {
        public Form1() {
            InitializeComponent();
        }
    
        private void text1_TextChanged(object sender, EventArgs e) {
            label1.AutoSize = false; //
            label1.Text = ((TextBox)sender).Text;
            using (var g = label1.CreateGraphics()) {
                label1.ClientSize = MeasureClientSize(g, label1, 100);
            }
        }
    
        internal static Size MeasureClientSize(Graphics g, Label label, int maxWidth) {
            Size size;
            int tmpWidth = maxWidth - (label.Padding.Left + label.Padding.Right);
            if (label.UseCompatibleTextRendering) {
                using (StringFormat stringFormat = CreateStringFormat(label)) {
                    SizeF tmpSizeF = g.MeasureString(label.Text, label.Font, tmpWidth, stringFormat);
                    size = new Size(Roundup(tmpSizeF.Width), Roundup(tmpSizeF.Height));
                }
            } else {
                TextFormatFlags flags = CreateTextFormatFlags(label);
                Size tmpSize = new Size(tmpWidth, 1);
                size = TextRenderer.MeasureText(g, label.Text, label.Font, tmpSize, flags);
            }
            return new Size(size.Width + label.Padding.Left + label.Padding.Right,
                            size.Height + label.Padding.Top + label.Padding.Bottom);
        }
    
        internal static int Roundup(double value) {
            return (int)Math.Truncate((value * 10 + 9) / 10);
        }
    
        internal static StringFormat CreateStringFormat(Label label) {
            // Please check .NET source and rewrite it.
            return new StringFormat(StringFormatFlags.FitBlackBox);
        }
    
        internal static TextFormatFlags CreateTextFormatFlags(Label label) {
            // Please check .NET source and rewrite it.
            return TextFormatFlags.TextBoxControl | TextFormatFlags.WordBreak;
        }
    }
    

    enter image description here

    0 comments No comments

1 additional answer

Sort by: Most helpful
  1. KOZ6.0 6,735 Reputation points
    2023-10-12T03:52:26.6333333+00:00

    The issue is in the following code.This code measures the length when they are lined up horizontally.

    SizeF size = label1.CreateGraphics().MeasureString(label1.Text, label1.Font);
    

    Please specify length you want to wrap and execute MeasureString. Don't forget to Dispose Grapchis object.:)

    int maxWidth = 50;
    SizeF size;
    using (var g = label1.CreateGraphics()) {
        size = g.MeasureString(label1.Text, label1.Font, maxWidth);
    }
    

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.