2010-05-25 8 views
6

he añadido a mi PresentationFramework.Aero App.xaml fusionaron los diccionarios, como en ...¿Cómo modifico el estilo predeterminado de un botón sin que WPF revierte de Aero a Classic?

<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> 

Estoy intentando modificar el aspecto predeterminado de los botones sólo un poco. Puedo poner este estilo en mi ButtonResourceDictionary:

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

Todos los botones tienen ahora el relleno correcto y texto en negrita, pero tienen un aspecto "clásico", no "Aero". ¿Cómo corrijo este estilo para que todos mis botones se vean Aero pero también tienen estos cambios menores? Preferiría no tener que configurar la propiedad Style para cada botón.

actualización

debería haber mencionado esto en primer lugar, pero si trato de usar BasedOn, como se muestra a continuación, aparece un StackOverflowException:

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

Esto normalmente trabajar, pero no con los diccionarios Aero fusionados. Si comento esos diccionarios, la excepción desaparece.

Actualización 2

Si añado un atributo x:Key y establecer manualmente el estilo, que funciona correctamente (estilo Aero con el acolchado y negrita), pero como he dicho, yo preferiría que el estilo es automáticamente aplicado globalmente a todos los botones.

Actualización 3

acabo de descubrir una nueva arruga. En mi aplicación, ButtonResourceDictionary.xaml se coloca en una biblioteca de clases (es decir, en un proyecto externo). Si muevo este archivo a una carpeta local, todo funciona bien. Entonces, el problema parece ser una mala interacción causada al hacer referencia a varios diccionarios de recursos externos. Estoy corrigiendo mi fragmento de código de App.xaml (arriba) para reflejar que ButtonResourceDictionary en realidad está definido externamente.

Respuesta

8

espero que haya encontrado una solución en el ínterin. Para todos los demás, here is one solución, y here is another. Sin embargo, no estoy seguro de si esto ayudará para su caso específico (especialmente el hecho de que hace referencia a un diccionario de recursos incrustado).

ACTUALIZACIÓN

he aquí una solución que se me ocurrió:

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

Dónde StaticApplicationResource es una MarkupExtension encargo escribí que simplemente llama 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; 
    } 
} 

De esta manera me Don No tengo que hacer referencia a mis diccionarios de recursos fuera de mi archivo App.xaml, que es la que más me gusta eso :). También puede poner lógica más complicada allí, lo que le permite resolver el estilo BasedOn de la manera que desee. Here is an excellent article que le muestra cómo cargar los diccionarios de recursos (y aquellos que el marco se resuelve automáticamente) desde el código.

+0

Gracias, Andre. Buena respuesta. Básicamente resolví el problema usando una técnica similar a su primera solución. Trasladé mis personalizaciones al estilo de botón predeterminado desde el nivel de la aplicación hasta el nivel de la ventana. – devuxer

0

Utilice el atributo BasedOn para heredar las propiedades del Aero Style. Esto debería solucionar tu problema.

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

De hecho, lo intenté, pero por alguna razón, causa una 'StackOverflowException'. Y, curiosamente, si hago un comentario sobre los diccionarios Aero fusionados, la excepción no ocurre. Entonces, por alguna razón, cuando te fusionas en Aero, no puedes basar un estilo en él. – devuxer

0

Sobre la base de sus actualizaciones, usted podría hacer esto (la verdad es horriblemente feo):

<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

Gracias, Abe, pero todavía causa una 'StackOverflowException'. – devuxer

+0

Falta un cierre cercano '}', debe ser: '' – Bolu

+0

¡Gracias por repararlo! –

Cuestiones relacionadas