How to do Chat Bubbles in VB.NET WinForms application
chat, vb.net, winforms
Solution
You can use a FlowlayoutPanel and a new Chatbubble usercontrol.
First you need to add a new usercontrol to your project. Call it `ChatBubble`. It's basically up to you if you use the `Control` class or the `UserControl` class. I used `Control` in my example by accident but it doesn't make much of a difference. The type is defined in the automatically created .Desiger. file by Visual Studio.
No define some properties of the control
Public Class ChatBubble
'The "Inherits Control/Usercontrol statement is found in the designer
Public Enum LeftRight
Left = 0
Right = 1
End Enum
Public Property Orientation As LeftRight
Public Property BackBrush As Brush
Orientation defines if the chat bubble is left or right aligned, Backbrush is the background color of the bubble.
A constructor is used to set some more parameters of the control
Public Sub New()
InitializeComponent()
SetStyle(ControlStyles.ResizeRedraw, True) 'Redraw the control on resize
SetStyle(ControlStyles.OptimizedDoubleBuffer, True) 'Double buffer the drawing
SetStyle(ControlStyles.AllPaintingInWmPaint, True) 'Used to draw the control yourself
SetStyle(ControlStyles.UserPaint, True) 'Used to draw the control yourself
BackBrush = Brushes.Blue 'Default values
Orientation = LeftRight.Left 'Default values
Me.Padding = New Padding(5) 'Default values
End Sub
The default text property is used for the chat text.
Now you actually need to draw the control
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
MyBase.OnPaint(e)
'Smooth the output
e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
'Measure the size of your content
Dim textSize As SizeF = e.Graphics.MeasureString(Me.Text, Me.Font)
'Ellipse defines the extents of the bubble
Dim Ellipse As Rectangle
'Setup the ellipse depending on the orientation
'Include margins (5 inside, padding of the control outside)
If Orientation = LeftRight.Left Then
Ellipse = New Rectangle(Me.ClientRectangle.Left + Me.Padding.Left, Me.ClientRectangle.Top + Me.Padding.Top, _
textSize.Width + 10, Me.ClientRectangle.Height - Me.Padding.Bottom - Me.Padding.Top)
Else
Ellipse = New Rectangle(Me.ClientRectangle.Right - (textSize.Width + 10) - Me.Padding.Right, Me.ClientRectangle.Top + Me.Padding.Top, _
textSize.Width + 10, Me.ClientRectangle.Height - Me.Padding.Bottom - Me.Padding.Top)
End If
'Define the text's location, center top/bottom
Dim TextLocation As Point = New Point(Ellipse.Left + 5, CInt(Me.ClientSize.Height / 2 - textSize.Height / 2))
'Draw the bubble
e.Graphics.FillEllipse(BackBrush, Ellipse)
'Draw the string
e.Graphics.DrawString(Me.Text, Me.Font, Brushes.White, TextLocation)
End Sub
This is a very rough example. You can autosize your control depending on your text, include text wrapping, but this basically does what you want. Add the bubbles to a Top/Bottom Flowlayoutpanel like this:
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'flp is the flowlayoutpanel
Static count As Integer = 1
Dim b As New ChatBubble
With b
.Text = "Hello World " & count.ToString
.Orientation = If(count Mod 2 = 0, ChatBubble.LeftRight.Left, ChatBubble.LeftRight.Right)
.Size = New Size(flp.Width, 30)
End With
flp.Controls.Add(b)
count += 1
End Sub
Private Sub flp_Resize(sender As Object, e As EventArgs) Handles flp.Resize
For Each c As Control In flp.Controls
c.Width = flp.Width
Next
End Sub
End Class
Sample output:
Problem
First, I would like to state that I am fairly new to the whole chat-bubble concept. I have done quite a bit of research and have come up void in results pertaining to how this can be done in a WinForms desktop application. The concept is rather simple (and common, especially in mobile devices) I would like to do this (ideally in a RichTextBox). Please remember, this is a WinForms application, so XAML components will not work. This is a chat layout issue only. Sending/receiving/displaying the messages is already done, I just need to know how to wrap those messages inside a bubble (left or right depending on communication direction), and display that in the form -- in a normal chat flow (currently using RichTextBox, and colorizing the name). Thanks in advance.