I want to create user control that will display text.
I need a way to resize control at run-time so that it will adjust height to show all the text.
I\'ve created contro
Here is an auto-height control. If you change the width of control, the height of control will changes in way which the whole text can be shown.
You can create such control using different approaches including:
Approach 1: Auto-size Composite Control hosting a Label
This approach is based on hosting an auto-size Label
with dynamic maximum width in an auto-size Control
. In this approach we set maximum width of label based on width of control and since the label is auto-size, its height will be automatically set to show all texts and then we set height of control based on height of label.
Approach 2: Auto-Size Simple Control from scratch without Label
This approach is based on overriding SetBoundsCore and setting size of control based on its Text
size. In this approach we calculate the size of text based on width of control using TextRenderer.MeasureText and then set calculated height as height of control. In this approach you should handle text format flags and rendering yourself.
In both approaches a ControlDesigner
is used to disable all size grab handles except left and right.
Please note
These are not the only approaches available but are good examples. As another option you can inherit from a Label
and change it's behavior.
It works based on setting AutoSize
property of label to true
and then setting MaximumSize
of label based on contol Width
. Also the height of control is set based on height of label.
You can simply draw the image in OnPaint
method. Also you can add a PictureBox
for image.
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
[Designer(typeof(MyLabelDesigner))]
public partial class MyLabel : Control
{
public MyLabel() { InitializeComponent(); }
private System.Windows.Forms.Label textLabel;
private void InitializeComponent()
{
this.textLabel = new System.Windows.Forms.Label();
this.textLabel.AutoSize = true;
this.textLabel.Location = new System.Drawing.Point(0, 0);
this.textLabel.Name = "label1";
textLabel.SizeChanged += new EventHandler(textLabel_SizeChanged);
this.AutoSize = true;
this.Controls.Add(this.textLabel);
}
void textLabel_SizeChanged(object sender, EventArgs e)
{
this.Height = this.textLabel.Bottom + 0;
}
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
this.textLabel.MaximumSize = new Size(this.Width, 0);
}
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public override string Text
{
get { return this.textLabel.Text; }
set { this.textLabel.Text = value; }
}
}
This approach works based on setting size of control in SetBoundsCore
based on current width and calculated height of its Text
. To calculate height of control. You can simply draw the Image
.
using System.Windows.Forms;
using System.Drawing;
using System.ComponentModel;
using System.Windows.Forms.Design;
[Designer(typeof(MyLabelDesigner))]
public class ExLabel : Control
{
public ExLabel()
{
AutoSize = true;
DoubleBuffered = true;
SetStyle(ControlStyles.ResizeRedraw, true);
}
protected override void OnTextChanged(System.EventArgs e)
{
base.OnTextChanged(e);
SetBoundsCore(Left, Top, Width, Height, BoundsSpecified.Size);
Invalidate();
}
protected override void SetBoundsCore(int x, int y, int width, int height,
BoundsSpecified specified)
{
var flags = TextFormatFlags.Left | TextFormatFlags.WordBreak;
var proposedSize = new Size(width, int.MaxValue);
var size = TextRenderer.MeasureText(Text, Font, proposedSize, flags);
height = size.Height;
base.SetBoundsCore(x, y, width, height, specified);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
var flags = TextFormatFlags.Left | TextFormatFlags.WordBreak;
TextRenderer.DrawText(e.Graphics, Text, Font, ClientRectangle,
ForeColor, BackColor, flags);
}
}
Here is the ControlDesigner
which used to limit size grab handles in designer to left and right for both implementations:
using System.Windows.Forms.Design;
public class MyLabelDesigner : ControlDesigner
{
public override SelectionRules SelectionRules
{
get
{
return (base.SelectionRules & ~(SelectionRules.BottomSizeable |
SelectionRules.TopSizeable));
}
}
}