2009-11-06 4 views
4

J'ai peut-être manqué quelque chose d'évident avec WPF, mais est-il possible de créer des styles qui fonctionnent hiérarchiquement avec les contrôles enfants du contrôle ciblé? Pour mieux expliquer, pensez à la façon dont CSS fonctionne pour le style HTML. Vous pouvez cibler les contrôles avec CSS hiérarchisés par sélecteurs:Hiérarchie de style WPF?

div > span em 
{ 
    color: blue; 
} 

ul.class > li ul li 
{ 
    display: block; 
    margin: 0px; 
} 

Est-il possible d'obtenir la même chose avec des styles WPF? Jusqu'à présent, j'ai créé des styles pour chaque type de contrôle ou styles nommés que j'applique directement à un contrôle. Cependant, je finis avec beaucoup plus de styles que j'ai vraiment l'intention, et il est presque impossible de mettre en forme les structures de contrôle en tant que groupe.

Merci pour tout commentaire.

MISE À JOUR:

Voici un exemple de ce que je voudrais être en mesure de le faire. Notez que seul le contrôle ListView racine a un style appliqué. Je voudrais être en mesure de cibler l'un des contrôles enfants dans l'un des CellTemplates sans avoir à appliquer directement le style à chacun de ces contrôles enfants. Cela permet de mieux découpler et d'isoler le balisage d'affichage de ma vue du balisage de style, ce qui me donne beaucoup plus de liberté pour changer de style sans avoir à créer explicitement un style pour chaque contrôle de mon application entière.

<Grid> 
    <ListView Style="{StaticResource ProcessableItemsListView}"> 
    <ListView.View> 
     <GridView> 
     <GridViewColumn Width="10"> 
      <GridViewColumn.CellTemplate> 
      <Grid> 
       <CheckBox Value="{Binging ...}" /> 
      </Grid> 
      </GridViewColumn.CellTemplate> 
     </GridViewColumn> 
     <GridViewColumn Width="*"> 
      <GridViewColumn.CellTemplate> 
      <Grid> 
       <TextBlock Text="{Binding ...}" /> 
      </Grid> 
      </GridViewColumn.CellTemplate> 
     </GridViewColumn> 
     <GridViewColumn Width="80"> 
      <GridViewColumn.CellTemplate> 
      <Grid> 
       <Button Command="{Binding ...}">Process</Button> 
      </Grid> 
      </GridViewColumn.CellTemplate> 
     </GridViewColumn> 
     <GridViewColumn Width="120"> 
      <GridViewColumn.CellTemplate> 
      <Grid> 
       <ProgressBar Value="{Binding ...}" /> 
      </Grid> 
      </GridViewColumn.CellTemplate> 
     </GridViewColumn> 
     </GridView> 
    </ListView.View> 
    </ListBiew> 
</Grid> 
+1

Un peu tard, mais voir http://www.codeproject.com/Articles/36499/Using-CSS-Selectors-for-Styling-in-WPF –

+0

@BorisB. Merci! Des trucs géniaux! – jrista

Répondre

1

j'aurais fait ce commentaire, mais a manqué de personnages

Hmmm. Étant donné que la réponse de andyp d'utiliser des styles implicites ne résout pas votre problème, je peux penser à deux façons légèrement différentes de le faire. L'une consiste à faire de tous les contrôles de vos cellules de la grille des contrôles de contenu simples et de lier un objet de données à la propriété Content du contrôle. Vous pouvez ensuite créer des styles implicites ciblés sur votre objet de données, au lieu du type de contrôle de l'interface utilisateur. C'est à peu près la même chose que andyp suggéré mais juste en regardant d'un point de vue des données (qui peut ne pas fonctionner dans votre scénario)

L'autre solution que je pourrais penser est de créer un style ciblé à un UIElement racine que tous de vos contrôles de cellule de grille héritent de. Dans le style, ajoutez un déclencheur pour permuter certaines propriétés de votre contrôle en fonction d'une certaine valeur (Name, Tag, une autre liaison de données).

Pas sûr que l'un d'entre eux obtiendra ce que vous voulez, mais ça vaut le coup.

En outre, pourriez-vous poster un extrait de code qui montre plus clairement ce que vous essayez d'accomplir. Il peut y avoir une façon beaucoup plus simple de résoudre ce problème que je suis juste manquant.

0

Je ne suis pas à cent pour cent sûr si je vous comprends bien, mais je pense que ce que vous voulez est de style une classe de base et ont appliqué ce style à sa descendance aussi.

Donc, si, par exemple, vous voulez le style d'un ComboBox vous pourriez écrire:

<Style x:Key="ComboBoxStyle" TargetType="ComboBox"> 
    ... 
</Style> 

mais vous pouvez aussi écrire:

<Style x:Key="ComboBoxStyle" TargetType="Control"> 
    ... 
</Style> 

et ont ce style appliqué à tous les descendants de Contrôlez au lieu de simplement les ComboBox. L'exemple est (directement et sans modification) tiré du blog this.

+0

Votre proche, mais j'en ai besoin un peu plus loin. Son plus dans le sens de ceci: Pour un type particulier de ListView avec une grille comme le contrôle de la racine de son modèle d'éléments, style le contrôle de bouton dans la cellule X, Y avec ce style. Est-ce que ça fait plus de sens? – jrista

+0

oui, je pense que je comprends maintenant ce que vous voulez dire, mais je n'ai aucune idée de la façon de réaliser cela dans WPF. Le seul moyen que je connaisse est d'utiliser un style nommé et de l'appliquer à ce bouton (ce qui semble être ce que vous voulez éviter). Pardon. – andyp

0

Vous pouvez obtenir l'héritage de style similaire à la façon dont le CSS en utilisant notamment le attribtue BasedOn

<Style x:Key="A"> 
    <Setter Property="Background" Value="Blue" /> 
</Style> 

<Style x:Key="B" BasedOn="{StaticResource A}"> 
    <Setter Property="Foreground" Value="Red" /> 
</Style> 

<Style x:Key="C" BasedOn="{StaticResource A"> 
    <Setter Property="Foreground" Value="White" /> 
</Style> 

Est-ce que l'aide?

+1

Ce n'est pas vraiment l'héritage de style. Pensez à une structure hiérarchique, par exemple une listview avec une grille dans son itemtemplate, et la grille contient différents contrôles dans ses cellules. Comment puis-je hiérarchiquement cibler l'un des contrôles dans une cellule de cette liste, sans avoir à appliquer explicitement le style directement au contrôle? Avec CSS, je peux cibler avec un sélecteur: .listview .grid button {...} – jrista