2010-04-28 7 views
5

Ho bisogno di reinventare/ricreare il Label Control da zero per aggiungere la mia propria immagine ad esso. Sì, so cosa stai pensando (e se non lo stai pensando, non dovresti esserlo?).Re-Inventing the Label Control

Qualcuno può indicarmi la giusta direzione?

Grazie.

L'intero scopo per ricreare l'etichetta è che voglio il pieno controllo su come viene disegnato sullo schermo, e in modo che possa avere anche KeyDown Event Handlers per esso. Ad esempio, l'utente può modificare il contenuto di un'etichetta nello stesso modo in cui modifica il contenuto di un controllo TextBox.

Inoltre, non posso semplicemente utilizzare un controllo TextBox, in quanto richiederebbe quasi, se non più lavoro per ottenere il risultato desiderato.

+2

io non sono sicuro che sto pensando quello che si pensava che stavo pensando ... – Paddy

+1

Cosa vuoi che faccia? Oltre a suggerire, come ha fatto Kyle, di estendere quello attuale, è impossibile rispondere alla domanda in modo costruttivo senza ulteriori informazioni. – itsmatt

+1

Andare a conquistare il mondo Pinky? – Mike

risposta

1

Creare il proprio controllo etichetta è abbastanza semplice, è sufficiente iniziare con Controllo e sovrascrivere OnPaint(). Quello che sta per byte è trasformarlo in un controllo che ha anche un comportamento di messa a fuoco. E consente all'utente di modificare il testo. Quando hai finito, avrai re-inventato il controllo TextBox. Il che è molto più difficile di quanto sembri.

Concentrarsi prima sulla messa a fuoco, questo è il problema più difficile. Non è molto probabile che l'utente vorrà focalizzare il controllo frequentemente. Forse una specie di stretta di mano segreta, come un doppio clic. Quando ne rilevi uno, puoi creare un controllo TextBox e metterlo davanti all'etichetta. E disponila quando perde lo stato attivo, aggiornando la proprietà Text dell'etichetta. O un semplice menu di scelta rapida che visualizza una piccola finestra di modifica.

Un esempio che utilizza il doppio clic per modificare l'approccio:

using System; 
using System.Windows.Forms; 

class MyLabel : Label { 
    private TextBox mEditor; 
    protected override void OnDoubleClick(EventArgs e) { 
    if (mEditor == null) { 
     mEditor = new TextBox(); 
     mEditor.Location = this.Location; 
     mEditor.Width = this.Width; 
     mEditor.Font = this.Font; 
     mEditor.Text = this.Text; 
     mEditor.SelectionLength = this.Text.Length; 
     mEditor.Leave += new EventHandler(mEditor_Leave); 
     this.Parent.Controls.Add(mEditor); 
     this.Parent.Controls.SetChildIndex(mEditor, 0); 
     mEditor.Focus(); 
    } 
    base.OnDoubleClick(e); 
    } 
    void mEditor_Leave(object sender, EventArgs e) { 
    this.Text = mEditor.Text; 
    mEditor.Dispose(); 
    mEditor = null; 
    } 
    protected override void Dispose(bool disposing) { 
    if (disposing && mEditor != null) mEditor.Dispose(); 
    base.Dispose(disposing); 
    } 
} 
+1

Hmmm interessante. .. Ti è mai capitato di conoscere qualche tutorial/documentazione che mi avrebbe messo nella giusta direzione per creare un nuovo Label e/o controllo TextBox? –

+0

@ j-t-s: qualsiasi libro decente di Windows Form dovrebbe aiutarti a iniziare. Ho aggiornato il mio post con un controllo di esempio che consente la modifica con un doppio clic. –

5

Perché non estendere solo quello attuale?

class MyMojoLabel : Label // Kind of thing

+0

Ho fatto questo nel mio progetto attuale, principalmente per fare cambiamenti linguistici dinamici e per ridurre lo sfarfallio. – Skizz

+0

Il suo punto non è quello di fare questo da quello che ho capito. Classe MyMojoLabel: UserControl sembra un inizio migliore. –

+0

@Bastiaan Linders - Non penso che un controllo utente sarebbe ciò di cui parlava l'op. I livelli di complessità vanno da 'classe MyMojoLabel: Control' a' classe MyMojoLabel: Label' a 'classe MyMojoLabel: UserControl'. Un controllo utente è fondamentalmente solo un gruppo di controlli esistenti. – stevehipwell

3

Un buon punto di partenza sarebbe forse per capire come Microsoft ha implementato l'etichetta.

Per ottenere un aspetto più approfondito, è necessario dare un'occhiata con Reflector nella classe o debugging the source code del controllo Label.

2
public class MyLabel : System.Windows.Forms.Label 
{ 
    protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) 
    { 
     base.OnPaint(e); 
     // or leave base out 

     // you would determine these values by the length of the text 
     e.Graphics.DrawEllipse(new System.Drawing.Pen(System.Drawing.Color.Red), 
           0, 0, 50, 12); 

    } 

    protected override void OnKeyDown(System.Windows.Forms.KeyEventArgs e) 
    { 
     base.OnKeyDown(e); 

     // although a label has a KeyDown event I don't know how it would 
     // receive focus, maybe you should create a text box that looks 
     // like a label 
    } 
} 

Che ne dici di questo?

+0

Sembra che abbiamo avuto la stessa idea allo stesso tempo, +1 per l'override di OnKeyDown (e per l'utilizzo del rosso come colore demo) – invert

2

Creare una classe che eredita da Control. Usa la chiamata SetStyle() per abilitare la pittura utente e il buffering doppio, e sostituisci OnPaint(), e qualsiasi altro metodo di cui hai bisogno.

class MyLabel : System.Windows.Forms.Control 
{ 
    public MyLabel() 
    { 
     this.SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true); 
    } 

    protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) 
    { 
     base.OnPaint(e); 
     ControlPaint.DrawBorder3D( e.Graphics, this.ClientRectangle, Border3DStyle.Etched, Border3DSide.All); 
     e.Graphics.DrawString(this.Text, this.Font, Brushes.Red, 0, 0); 
    } 
}