2010-05-25 7 views
6

J'ai ajouté à mon PresentationFramework.Aero App.xaml fusionné dictionnaires, comme dans ...Comment modifier le style par défaut d'un bouton sans que WPF ne revienne d'Aero à 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> 

Je suis en train de modifier l'apparence par défaut des boutons légèrement. Je mis ce style dans mon ButtonResourceDictionary:

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

Tous les boutons ont maintenant le rembourrage correct et texte en gras, mais ils regardent « Classic », pas « Aero ». Comment puis-je corriger ce style afin que mes boutons aient tous l'air Aero mais aussi ces changements mineurs? Je préférerais ne pas avoir à définir la propriété Style pour chaque bouton.

Mise à jour

je aurais dû le mentionner en premier lieu, mais si je tente d'utiliser BasedOn, comme indiqué ci-dessous, je reçois un StackOverflowException:

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

Cela devrait normalement travailler, mais pas avec les dictionnaires Aero fusionnés. Si je commente ces dictionnaires, l'exception disparaît.

Mise à jour 2

Si j'ajoute un attribut x:Key et régler manuellement le style, il fonctionne correctement (style Aero avec rembourrage et gras), mais comme je le disais, je préférerais que le style est automatiquement appliqué globalement à tous les boutons.

Mise à jour 3

Je viens de découvrir une nouvelle ride. Dans mon application, ButtonResourceDictionary.xaml est placé dans une bibliothèque de classes (c'est-à-dire dans un projet externe). Si je déplace ce fichier vers un dossier local, tout fonctionne correctement. Ainsi, le problème semble être une mauvaise interaction causée par le référencement de divers dictionnaires de ressources externes. Je corrige mon extrait de code App.xaml (ci-dessus) pour indiquer que ButtonResourceDictionary est défini en externe.

Répondre

8

J'espère que vous avez trouvé une solution dans l'intervalle. Pour tout le monde, solution de contournement here is one et here is another. Je ne suis pas sûr que cela vous aidera dans votre cas spécifique (en particulier le fait que vous faites référence à un dictionnaire de ressources intégré).

MISE À JOUR

est ici une solution, je suis venu avec:

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

StaticApplicationResource est un MarkupExtension personnalisé j'ai écrit qui appelle simplement 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 cette façon, je don Je n'ai pas besoin de référencer mes dictionnaires de ressources en dehors de mon fichier App.xaml, ce qui est comme je l'aime il :). Vous pouvez également mettre une logique plus compliquée là-dedans, vous permettant de résoudre le style BasedOn comme vous le souhaitez. Here is an excellent article vous montrant comment charger des dictionnaires de ressources (et ceux que l'infrastructure résout automatiquement) à partir du code.

+0

Merci, André. Bonne réponse. J'ai essentiellement résolu le problème en utilisant une technique similaire à votre première solution de contournement. J'ai déplacé mes personnalisations au style de bouton par défaut du niveau de l'application au niveau de la fenêtre. – devuxer

0

Utilisez l'attribut BasedOn pour hériter des propriétés du style Aero. Cela devrait résoudre votre problème.

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

J'ai effectivement essayé cela, mais pour une raison quelconque, il provoque une 'StackOverflowException'. Et, fait intéressant, si je commente les dictionnaires Aero fusionnés, l'exception ne se produit pas. Donc, pour une raison quelconque, lorsque vous fusionnez dans Aero, vous ne pouvez pas baser un style dessus. – devuxer

0

Sur la base de vos mises à jour, vous pouvez le faire (il est vrai qu'il est laid hideusement):

<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

Merci, Abe, mais cela provoque toujours une 'StackOverflowException'. – devuxer

+0

Missing une accolade étroite '}', devrait être: '