Sovrascrivere lo sfondo del pulsante in WPF su Aero

Quindi, il desiderio è semplice, cambia lo sfondo di un pulsante in LightGreen, Green quando il cursore del mouse passa sopra di esso e DarkGreen quando viene premuto. Il seguente XAML è il mio primo tentativo:

      

Ma, purtroppo, questo non funziona. Siamo solo 1/3 del cammino verso l’objective. Sì, il pulsante diventa verde chiaro, ma non appena si passa con il mouse su di esso o premuto si ottiene il cromo Aero standard per i rispettivi stati dei pulsanti. Non volendo mollare, provo la seguente dissolutezza:

 ...    ... 

Ora abbiamo gettato il modello di controllo del tutto originale lanciato da Aero.NormalColor.xaml . Ahimè, questo non cambia nulla. Passo quindi alla rimozione di due attributi ( RenderPressed e RenderMouseOver ) dall’elemento Microsoft_Windows_Themes:ButtonChrome . Tuttavia, non ci sono cambiamenti. Quindi rimuovo l’impostazione dell’attributo Background del pulsante, lasciando solo la dichiarazione dello spazio dei nomi per l’assembly PresentationFramework.Aero:

 ... 

Finalmente, abbiamo progressi. Siamo passati da 1/3 dei requisiti a 2/3 del modo, con IsMouseOver e IsPressed in funzione, ma non lo sfondo verde chiaro durante lo stato normale del pulsante (di cui non è stato premuto il mouse o premuto), dal momento che ho rimosso la proprietà Background dal pulsante, per applicare gli altri due stati e renderli visibili. Ora, dopo che questo XAML maniacale non riesce a ottenere lo sfondo LightGreen per il normale stato del pulsante, modifico lo stile per inserire anche il colore dello sfondo:

  <Button xmlns... <ControlTemplate... ...    

Infine, funziona come previsto.

Sono pazzo, o questi (e più) i cerchi devi passare attraverso un tema Aero per cambiare semplicemente il colore di sfondo di un pulsante in alcuni dei suoi vari stati (normale, al passaggio del mouse, premuto)? Forse, la vita non sarebbe così male se non dovessi includere l’intero RenderMouseOver RenderPressed qui dentro solo per rimuovere i due attributi ( RenderMouseOver e RenderPressed ) da esso.

Grazie per qualsiasi aiuto – Sono alla fine dello spirito.

Aggiornamento: Ma aspetta c’è di più in questo. Invece di rimuovere gli attributi RenderMouseOver e RenderPressed dal modello di controllo, semplicemente cambiandoli da:

 <Microsoft_Windows_Themes:ButtonChrome SnapsToDevicePixels="true" ... RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}" ... 

a:

 <Microsoft_Windows_Themes:ButtonChrome SnapsToDevicePixels="true" ... RenderMouseOver="{Binding IsMouseOver}" RenderPressed="{Binding IsPressed}" ... 

…, risolve anche il problema (di ignorare i trigger di stile del pulsante). Penso che la radice del problema sia che i bind di template sono applicati in fase di compilazione (per ragioni di performance), mentre i binding regolari vengono applicati in fase di esecuzione. Per questo motivo, i binding dai trigger di stile dei singoli pulsanti non vengono utilizzati se gli attributi utilizzano i collegamenti dei modelli (ad esempio, vengono utilizzati IsMouseOver e IsPressed dal modello originale).

Dopo aver detto tutto quanto sopra, ecco l’esempio canonico per cambiare lo sfondo di un pulsante in Aero mantenendo il suo modello di controllo originale:

        

Questo ovviamente presuppone che solo un pulsante sia così stilizzato, altrimenti il ​​modello e lo stile possono essere spostati in una sezione risorse da qualche parte. Inoltre, non esiste alcun trigger per lo stato di default di un pulsante, ma è facilmente aggiunto all’esempio precedente (non dimenticare di modificare l’attributo RenderDefaulted nel modello di controllo per utilizzare Binding anziché TemplateBinding).

Se qualcuno ha qualche suggerimento su come sovrascrivere TemplateBinding con Binding per solo i due attributi nel modello di controllo che devono essere modificati, senza ripetere l’intera definizione di chrome dall’aero xaml all’ingrosso, sono tutto orecchie.

Il modello predefinito per Button utilizza ButtonChrome , che esegue il proprio disegno. Se vuoi eliminare completamente l’aspetto predefinito, devi definire il tuo modello, senza ButtonChrome . So che sembra noioso, ma devi farlo una sola volta: puoi mettere il tuo stile personalizzato in un dizionario delle risorse e fare semplicemente riferimento ad esso con StaticResource . Tieni presente che puoi anche applicare lo stile a tutti i pulsanti della tua app utilizzando {x:Type Button} come chiave dello stile ( x:Key attributo x:Key )