2010-05-25 8 views
6

Ho aggiunto al mio PresentationFramework.Aero App.xaml fusi dizionari, come in ...Come si modifica lo stile predefinito di un pulsante senza che WPF venga ripristinato da Aero a Classico?

<Application 
    x:Class="TestApp.App" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <Application.Resources> 
     <ResourceDictionary> 
      <ResourceDictionary.MergedDictionaries> 
       <ResourceDictionary 
        Source="/PresentationFramework.Aero;component/themes/Aero.NormalColor.xaml" /> 
       <ResourceDictionary 
        Source="pack://application:,,,/WPFToolkit;component/Themes/Aero.NormalColor.xaml" /> 
       <ResourceDictionary 
        Source="/CommonLibraryWpf;component/ResourceDictionaries/ButtonResourceDictionary.xaml" /> 
        <!-- Note, ButtonResourceDictionary.xaml is defined in an external class library--> 
      </ResourceDictionary.MergedDictionaries> 
     </ResourceDictionary> 
    </Application.Resources> 
</Application> 

sto cercando di modificare leggermente l'aspetto predefinito di pulsanti. Ho messo questo stile nel mio ButtonResourceDictionary:

<Style TargetType="Button"> 
    <Setter Property="Padding" Value="3" /> 
    <Setter Property="FontWeight" Value="Bold" /> 
</Style> 

Tutti i pulsanti hanno ora l'imbottitura corretta e il testo in grassetto, ma hanno un aspetto "classico", non "Aero". Come posso risolvere questo stile in modo che i miei pulsanti abbiano tutti l'aspetto Aero ma anche questi piccoli cambiamenti? Preferirei non dover impostare la proprietà Style per ogni pulsante.

Aggiornamento

avrei parlato di questo, in primo luogo, ma se provo ad usare BasedOn, come illustrato di seguito, ho ottenere un StackOverflowException:

<Style BasedOn="{StaticResource {x:Type Button}}" TargetType="{x:Type Button}"> 
    <Setter Property="Padding" Value="3" /> 
    <Setter Property="FontWeight" Value="Bold" /> 
</Style> 

Questo normalmente lavorare, ma non con i dizionari Aero uniti. Se commento quei dizionari, l'eccezione scompare.

Update 2

Se posso aggiungere un attributo x:Key e impostare manualmente lo stile, funziona correttamente (in stile Aero con imbottitura e grassetto), ma come ho detto, preferirei che lo stile è automaticamente applicato globalmente a tutti i pulsanti.

Aggiornamento 3

Ho appena scoperto una nuova ruga. Nella mia app, ButtonResourceDictionary.xaml viene inserito in una libreria di classi (ad esempio, in un progetto esterno). Se sposto questo file in una cartella locale, tutto funziona correttamente. Quindi, il problema sembra essere una cattiva interazione causata dal riferimento a vari dizionari di risorse esterne. Sto correggendo il mio snippet di codice App.xaml (sopra) per riflettere che ButtonResourceDictionary è effettivamente definito esternamente.

risposta

8

Spero che hai trovato una soluzione nel frattempo. Per tutti gli altri, soluzione alternativa here is one e here is another. Non sono sicuro se ciò sarà di aiuto per il tuo caso specifico (specialmente il fatto che fai riferimento a un dizionario di risorse incorporato).

UPDATE

Ecco una soluzione mi è venuta:

<Style TargetType="TextBox" BasedOn="{Common:StaticApplicationResource {x:Type TextBox}}"> 
    <Setter Property="Height" Value="21"/> 
</Style> 

Dove StaticApplicationResource è un MarkupExtension personalizzato ho scritto che semplicemente chiama TryFindResource:

[MarkupExtensionReturnType(typeof(object))] 
public class StaticApplicationResource : MarkupExtension 
{ 
    public StaticApplicationResource(object pResourceKey) 
    { 
     mResourceKey = pResourceKey; 
    } 

    private object _ResourceKey; 

    [ConstructorArgument("pResourceKey")] 
    public object mResourceKey 
    { 
     get { return _ResourceKey; } 
     set { _ResourceKey = value; } 
    } 

    public override object ProvideValue(IServiceProvider serviceProvider) 
    { 
     if (mResourceKey == null) 
      return null; 

     object o = Application.Current.TryFindResource(mResourceKey); 

     return o; 
    } 
} 

In questo modo ho don Devo fare riferimento ai miei dizionari delle risorse al di fuori del mio file App.xaml, che è il modo che mi piace :) Puoi anche inserire logica più complicata anche lì, permettendoti di risolvere lo stile BasedOn come più ti piace. Here is an excellent article che mostra come caricare i dizionari delle risorse (e quelli che il framework risolve automaticamente) dal codice.

+0

Grazie, Andre. Buona risposta. Ho praticamente risolto il problema utilizzando una tecnica simile alla tua prima soluzione. Ho spostato le mie personalizzazioni sullo stile del pulsante predefinito dal livello App al livello Finestra. – devuxer

0

Utilizzare l'attributo BasedOn per ereditare le proprietà dallo stile Aero. Questo dovrebbe risolvere il tuo problema.

<Style 
    BasedOn="{StaticResource {x:Type Button}}" 
    TargetType="{x:Type Button}"> 
    <Setter Property="Padding" Value="3" /> 
    <Setter Property="FontWeight" Value="Bold" /> 
</Style> 
+0

In realtà l'ho provato, ma per qualche motivo, causa un 'StackOverflowException'. E, cosa interessante, se commento i dizionari uniti di Aero, l'eccezione non si verifica. Quindi, per qualche motivo, quando ti unisci in Aero, non puoi basare uno stile su di esso. – devuxer

0

Sulla base di aggiornamenti, si potrebbe fare questo (bisogna ammettere che è orribilmente brutto):

<Style x:Key="_buttonStyleBase" 
     BasedOn="{StaticResource {x:Type Button}}" 
     TargetType="{x:Type Button}"> 
    <Setter Property="Padding" Value="3" /> 
    <Setter Property="FontWeight" Value="Bold" /> 
</Style> 

<Style TargetType="{x:Type Button}" 
     BasedOn="{StaticResource _buttonStyleBase}" /> 
+0

Grazie, Abe, ma causa ancora un 'StackOverflowException'. – devuxer

+0

Manca una parentesi chiusa '}', dovrebbe essere: '