Winform C#.NET:È possibile sovrascrivere Label.Autosize?
Domanda
Non mi piace la proprietà AutoSize del controllo Label.Ho un'etichetta personalizzata che, tra le altre cose, disegna un elegante bordo arrotondato.Sto inserendo un AutoSize = false
nel mio costruttore, tuttavia, quando lo inserisco in modalità progettazione, la proprietà è sempre True.
Ho sovrascritto altre proprietà con successo, ma questa mi ignora felicemente.Qualcuno ha la minima idea se questo è "progettato da MS"?
Ecco il codice sorgente completo della mia etichetta nel caso qualcuno sia interessato.
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace Dentactil.UI.WinControls
{
[DefaultProperty("TextString")]
[DefaultEvent("TextClick")]
public partial class RoundedLabel : UserControl
{
private static readonly Color DEFAULT_BORDER_COLOR = Color.FromArgb( 132, 100, 161 );
private const float DEFAULT_BORDER_WIDTH = 2.0F;
private const int DEFAULT_ROUNDED_WIDTH = 16;
private const int DEFAULT_ROUNDED_HEIGHT = 12;
private Color mBorderColor = DEFAULT_BORDER_COLOR;
private float mBorderWidth = DEFAULT_BORDER_WIDTH;
private int mRoundedWidth = DEFAULT_ROUNDED_WIDTH;
private int mRoundedHeight = DEFAULT_ROUNDED_HEIGHT;
public event EventHandler TextClick;
private Padding mPadding = new Padding(8);
public RoundedLabel()
{
InitializeComponent();
}
public Cursor TextCursor
{
get { return lblText.Cursor; }
set { lblText.Cursor = value; }
}
public Padding TextPadding
{
get { return mPadding; }
set
{
mPadding = value;
UpdateInternalBounds();
}
}
public ContentAlignment TextAlign
{
get { return lblText.TextAlign; }
set { lblText.TextAlign = value; }
}
public string TextString
{
get { return lblText.Text; }
set { lblText.Text = value; }
}
public override Font Font
{
get { return base.Font; }
set
{
base.Font = value;
lblText.Font = value;
}
}
public override Color ForeColor
{
get { return base.ForeColor; }
set
{
base.ForeColor = value;
lblText.ForeColor = value;
}
}
public Color BorderColor
{
get { return mBorderColor; }
set
{
mBorderColor = value;
Invalidate();
}
}
[DefaultValue(DEFAULT_BORDER_WIDTH)]
public float BorderWidth
{
get { return mBorderWidth; }
set
{
mBorderWidth = value;
Invalidate();
}
}
[DefaultValue(DEFAULT_ROUNDED_WIDTH)]
public int RoundedWidth
{
get { return mRoundedWidth; }
set
{
mRoundedWidth = value;
Invalidate();
}
}
[DefaultValue(DEFAULT_ROUNDED_HEIGHT)]
public int RoundedHeight
{
get { return mRoundedHeight; }
set
{
mRoundedHeight = value;
Invalidate();
}
}
private void UpdateInternalBounds()
{
lblText.Left = mPadding.Left;
lblText.Top = mPadding.Top;
int width = Width - mPadding.Right - mPadding.Left;
lblText.Width = width > 0 ? width : 0;
int heigth = Height - mPadding.Bottom - mPadding.Top;
lblText.Height = heigth > 0 ? heigth : 0;
}
protected override void OnLoad(EventArgs e)
{
UpdateInternalBounds();
base.OnLoad(e);
}
protected override void OnPaint(PaintEventArgs e)
{
SmoothingMode smoothingMode = e.Graphics.SmoothingMode;
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
int roundedWidth = RoundedWidth > (Width - 1)/2 ? (Width - 1)/2 : RoundedWidth;
int roundedHeight = RoundedHeight > (Height - 1)/2 ? (Height - 1)/2 : RoundedHeight;
GraphicsPath path = new GraphicsPath();
path.AddLine(0, roundedHeight, 0, Height - 1 - roundedHeight);
path.AddArc(new RectangleF(0, Height - 1 - 2*roundedHeight, 2*roundedWidth, 2*roundedHeight), 180, -90);
path.AddLine(roundedWidth, Height - 1, Width - 1 - 2*roundedWidth, Height - 1);
path.AddArc(new RectangleF(Width - 1 - 2*roundedWidth, Height - 1 - 2*roundedHeight, 2*roundedWidth, 2*roundedHeight), 90, -90);
path.AddLine(Width - 1, Height - 1 - roundedHeight, Width - 1, roundedHeight);
path.AddArc(new RectangleF(Width - 1 - 2*roundedWidth, 0, 2*roundedWidth, 2*roundedHeight), 0, -90);
path.AddLine(Width - 1 - roundedWidth, 0, roundedWidth, 0);
path.AddArc(new RectangleF(0, 0, 2*roundedWidth, 2*roundedHeight), -90, -90);
e.Graphics.DrawPath(new Pen(new SolidBrush(BorderColor), BorderWidth), path);
e.Graphics.SmoothingMode = smoothingMode;
base.OnPaint(e);
}
protected override void OnResize(EventArgs e)
{
UpdateInternalBounds();
base.OnResize(e);
}
private void lblText_Click(object sender, EventArgs e)
{
if (TextClick != null)
{
TextClick(this, e);
}
}
}
}
(ci sono alcuni problemi con il markup di Stack Overflow e il carattere di sottolineatura, ma è facile seguire il codice).
In realtà ho rimosso l'override qualche tempo fa quando ho visto che non funzionava.Lo aggiungerò di nuovo adesso e lo testerò.Fondamentalmente voglio sostituire l'etichetta con una nuova etichetta chiamata:IWillNotAutoSizeLabel ;)
Fondamentalmente odio la proprietà autosize "attiva per impostazione predefinita".
Soluzione
Ho riscontrato un comportamento simile durante l'impostazione di determinate proprietà dei controlli nel costruttore del modulo stesso.Sembra che ritornino alle impostazioni predefinite in fase di progettazione.
Ho notato che stai già sovrascrivendo il metodo OnLoad.Hai provato a impostare AutoSize = false lì?Oppure ti preoccupi principalmente di fornire a predefinito valore di falso?
Altri suggerimenti
Ci ho passato molto tempo e finalmente funziona!(il mio codice è vb.net ma è semplice convertirlo)
Private _Autosize As Boolean
Public Sub New()
_Autosize=False
End Sub
Public Overrides Property AutoSize() As Boolean
Get
Return MyBase.AutoSize
End Get
Set(ByVal Value As Boolean)
If _Autosize <> Value And _Autosize = False Then
MyBase.AutoSize = False
_Autosize = Value
Else
MyBase.AutoSize = Value
End If
End Set
End Property
Il tuo problema potrebbe essere che non stai effettivamente sovrascrivendo Autosize nel tuo codice (cioè, nello stesso modo in cui stai sovrascrivendo Font o ForeColor).
Non vedo this.AutoSize = false
nel tuo costruttore.La tua classe è contrassegnata come parziale: forse hai un costruttore in un altro file con quella riga.Il progettista dello studio visivo chiamerà il costruttore senza parametri che hai lì.