Ярлык в UserControl (Winforms) не показывает

Имейте UserControl с ярлыком, доморощенным "TextBox" (унаследованным непосредственно от Control) и Button. Цель состоит в том, чтобы наклейка "приклеивалась" к соответствующим элементам управления, поэтому дизайн форм более прост. Я переопределил событие OnPaint(), поэтому witdh из "TextBox" вычисляется с учетом ширины метки. Который, в свою очередь, имеет свой текст, взятый из назначаемого свойства UserControl. Таким образом, полная ширина UserControl - это то, что видно в дизайнере. Все вычисления выполнены правильно (когда текст для ярлыка больше, ширина текста меньше, а наоборот). Еще раз: если текст метки пуст, ярлык помечен как невидимый и тому подобное. Но ярлык не показан. Некоторые идеи? ТИА

2 ответа

Я последовал совету Шелл. Но с завихрением. Если вы попытаетесь выполнить DrawString() в событии UserControl OnPaint, то произойдет nohing, потому что OnPaint для формы запускается после всех элементов управления, поэтому он стирает текст. Я обратился к тому, чтобы создать метод в форме, в которой содержится UserControl, и установить его как интерфейс. Следующий код следует

Интерфейс и вспомогательный класс

public interface IKindForm
{
 void DisplayText( DisplayText t );
}

public class DisplayText
{
 public string Text { get; protected set; }
 public Font Font { get; protected set; }
 public Brush Brush { get; protected set; }
 public Point Point { get; protected set; }

 public DisplayText( string text, Font font, Color color, int x, int y )
 {
 Text = text;
 Font = font;
 Brush = new SolidBrush( color );
 Point = new Point( x, y );
 }
}

Метод в форме, которая реализует интерфейс и переопределенный OnPaint

private List<displaytext> textsToDisplay = new List<displaytext>();

 public void DisplayText( DisplayText t )
 {
 if (textsToDisplay.Contains( t ))
 return;
 textsToDisplay.Add( t );
 Invalidate();
 }

 protected override void OnPaint( PaintEventArgs e )
 {
 foreach (DisplayText t in textsToDisplay)
 e.Graphics.DrawString( t.Text, t.Font, t.Brush, t.Point );
 base.OnPaint( e );
 }
</displaytext></displaytext>

И, наконец, код в UserControl

bool labelRegistered = false;

 protected override void OnPaint( PaintEventArgs e )
 {

 int textStart = 0;
 SizeF ssize = new SizeF( 0, 0 );

 if (labelText != null && labelText != String.Empty) {
 ssize = e.Graphics.MeasureString( labelText, labelFont );
 textStart = (int)ssize.Width;
 }

 if (ssize.Width > 0) {
 if (this.TopLevelControl is IKindForm) {
 if (!labelRegistered) {
 int yPos = this.Location.Y + margin + ComboText.Size.Height / 4;
 int xPos = this.Location.X - ( textStart + labelOffset );
 ((IKindForm)this.TopLevelControl).DisplayText( new DisplayText( labelText, LabelFont, labelColor,
 xPos, yPos ) );
 }
 }
 labelRegistered = true;
 }

Единственным недостатком является то, что в дизайнере TopLevelControl не является IKindForm, поэтому вы не можете видеть "метку".


Вы не можете добавить метку в пользовательский элемент управления, унаследованный текстовым полем. вы должны поместить оба элемента управления (ярлык и текстовое поле) отдельно в пользовательский элемент управления вместо наследования. таким образом, вы можете установить размер и расположение текстового поля программно. и вы должны создать все свойства, которые хотите обрабатывать вне класса или пространства имен.

например

[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[Browsable(true)]
[DefaultValue(string.Empty)]
public override string Text
{
 get {
 return txtBox.Text;
 }
 set {
 txtBox.Text = value;
 }
}

[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[Browsable(true)]
[DefaultValue("My Lable:")] 
public string LabelText
{
 get{
 return lblLabel.Text;
 }
 Set {
 lblLabel.Text = value;
 }
}

licensed under cc by-sa 3.0 with attribution.