Na problem natknąłem się dzisiaj, kiedy w Legislatorze chciałem dorobić ładny pasek informacyjny. Napisanie takiej kontrolki bynajmniej nie okazało się kłopotliwe. Kod poniżej.
namespace System.Windows.Forms {
/// <summary>
/// Shrinkable labelc control class.
/// </summary>
public class LabelShrinkable : Label {
bool shrink = false;
string orginal = String.Empty;
/// <summary>
/// Raises the <see cref="E:System.Windows.Forms.Control.Resize"/> event.
/// </summary>
/// <param name="e">An <see cref="T:System.EventArgs"/> that contains the event data.</param>
protected override void OnResize(EventArgs e) {
base.OnResize(e);
if (!shrink) {
SrinkText();
}
}
/// <summary>
/// Raises the <see cref="E:System.Windows.Forms.Control.ClientSizeChanged"/> event.
/// </summary>
/// <param name="e">An <see cref="T:System.EventArgs"/> that contains the event data.</param>
protected override void OnClientSizeChanged(EventArgs e) {
base.OnClientSizeChanged(e);
if (!shrink) {
SrinkText();
}
}
/// <summary>
/// </summary>
/// <param name="e">An <see cref="T:System.EventArgs"/> that contains the event data.</param>
protected override void OnTextChanged(EventArgs e) {
base.OnTextChanged(e);
if (!shrink) {
orginal = this.Text;
SrinkText();
}
}
/// <summary>
/// Srinks the text.
/// </summary>
public void SrinkText() {
shrink = true;
try {
var textWidth = TextRenderer.MeasureText(orginal, this.Font).Width;
var controlWidth = this.Width;
var s = String.Empty;
if (textWidth > controlWidth) {
foreach (var c in orginal) {
s += c;
var w = TextRenderer.MeasureText(s + "... ", this.Font).Width;
if (w >= controlWidth) {
break;
}
}
this.Text = s + "...";
}
else {
this.Text = orginal;
}
}
finally {
this.Invalidate();
shrink = false;
}
}
}
}