2009-08-05 13 views
12

Posso cambiare l'icona di default usata su un Winform?Cambia l'icona di Winform di default su tutta l'app

La maggior parte dei miei moduli ha la proprietà di icona impostata su un'icona personalizzata. Per le poche forme che scivolano tra le fessure, non voglio la generica icona "hey look, ha fatto questo in visual studio".

Una soluzione è quella di controllare in modo noioso tutti i miei moduli per assicurarsi che abbiano un set di icone personalizzato o che ShowIcon sia impostato su False.

Un'altra soluzione è che tutte le mie forme vengano ereditate da una classe base che imposta un'icona personalizzata nel costruttore.

Oltre a quelle soluzioni, quali altre opzioni ho?

MODIFICA: Speravo che ci sarebbe stato un modo per sostituire la fonte dell'icona di borsa con la mia. Si trova in un file di risorse da qualche parte? O è incorporato in una DLL .NET che non posso (o in realtà, davvero non dovrebbe) modificare?

BOUNTY EDIT: C'è un modo per farlo senza modificare o scrivere una singola riga di codice? Non mi interessa quanto sia poco pratica, complicata, sprecata la soluzione ... voglio solo sapere se è possibile. Devo soddisfare la mia curiosità.

risposta

24

Il icona di predefinito è incorporato nel WinForms dll - guardando riflettore (DefaultIcon) è:

defaultIcon = new Icon(typeof(Form), "wfc.ico"); 

Non c'è magia in là che controlla un altro luogo comune, quindi non si può fare senza cambiare codice.

Si può sempre abbracciare le forze dell'oscurità con la riflessione basata sul campo? Nota: questo è hacky e fragile. Sulla tua testa! Ma funziona:

[STAThread] 
static void Main() { 
    // pure evil 
    typeof(Form).GetField("defaultIcon", 
      BindingFlags.NonPublic | BindingFlags.Static) 
     .SetValue(null, SystemIcons.Shield); 

    // all forms now default to a shield 
    using (Form form = new Form()) { 
     Application.Run(form); 
    } 
} 

Per farlo correttamente; due opzioni comuni;

  • una base Form classe che ha il set di icone
  • un metodo factory Form - forse qualcosa di simile:

codice:

public static T CreateForm<T>() where T : Form, new() { 
    T frm = new T(); 
    frm.Icon = ... 
    // any other common code 
    return frm; 
} 

Allora, invece di:

using(var frm = new MySpecificForm()) { 
    // common init code 
} 

Qualcosa di simile:

using(var frm = Utils.CreateForm<MySpecificForm>()) { 

} 

Naturalmente - che non è molto più bella! Un'altra opzione potrebbe essere un metodo di estensione C# 3.0, forse come API fluente:

public static T CommonInit<T>(this T form) where T : Form { 
    if(form != null) { 
     form.Icon = ... 
     //etc 
    } 
    return form; 
} 

e

using(var frm = new MySpecificForm().CommonInit()) { 
    // ready to use 
} 

Questo è quindi solo un .CommonInit() lontano dal codice esistente.

+0

Accettato per trovare effettivamente l'icona ... abbastanza vicino –

+0

Questo è assolutamente fantastico. Appena salvati dall'esecuzione su 50 moduli ... –

+0

L'opzione reflection ha funzionato benissimo e con l'API di riflessione della piattaforma O2, il codice per farlo non sembra così spaventoso typeof (Form) .fieldValue ("defaultIcon", SystemIcons .Scudo); –

4

L'opzione di classe base è quella che usiamo.

Se si sta cercando un'alternativa (non necessariamente di buona qualità), è possibile: 1. Utilizzare IOC per creare un'istanza di tutti i moduli e modificare il contenitore IOC per impostare l'icona dell'applicazione. 2. Utilizzare AOP per inserire il codice in tutti i moduli che impostano l'icona dell'applicazione.

Personalmente, mi basta usare la classe di base ...

0

Se tutti i moduli sono in un solo progetto, allora si può prendere la dll del progetto e utilizzare la reflection per ottenere ogni tipo nella DLL. Se il tipo deriva da Form, puoi impostare la proprietà Icon del tipo su qualsiasi cosa desideri. Non sono sicuro di quale sarà l'overhead delle prestazioni se il progetto è molto grande.

1

Se si desidera aggiornare tutte le icone di un altro, è possibile costruire una piccola applicazione che pubblica tutti i file * .Designer.vb (in vb.net) e aggiungendo la riga seguente per InitializeComponent:

Me.Icon = New System.Drawing.Icon("C:\PathTo\icon.ico") 

Spero che aiuti.

2

La mia risposta utile:

No

sarebbe una bella caratteristica per Microsoft per implementare, però, dal momento che la maggior parte delle applicazioni utilizzano la stessa icona in tutta l'intera applicazione.