2010-09-29 4 views
14

Existe-t-il un moyen de modifier (et d'appliquer) un style de manière dynamique dans WPF?Modification dynamique d'un style dans WPF

Dire que j'ai le style déclaré en XAML:

<Style TargetType="local:MyLine" 
      x:Key="MyLineStyleKey" x:Name="MyLineStyleName"> 
     <Setter Property="Fill" Value="Pink"/> 
     <Style.Triggers> 
      <Trigger Property="IsSelected" Value="true"> 
       <Setter Property="Fill" Value="Blue" />      
      </Trigger> 
     </Style.Triggers> 
    </Style> 
  1. En un instant, je dois changement la couleur Pink, à, dire Green, et toutes les lignes avec le style MyLineStyleKey est devenu vert . Une ligne est rose quand elle est libérée, et bleue quand elle est sélectionnée ... Maintenant, j'avais besoin de changer la propriété non sélectionnée (rose à vert) ..., donc ce n'est pas juste de le régler à une autre couleur, le déclencheur (sélection> Bleu) ne fonctionnera plus ... Est-ce possible? Comment?

  2. Est-ce possible à de lier à la couleur rose dans le style, disons, à un fond de bouton, qui reflétera la couleur de style actuellement utilisée?

EDIT:
Pour J'ai essayé:

Style s = (Style)this.Resources["MyLineStyleKey"]; 

(s.Setters[0] as Setter).Value = background; 
(s.Setters[1] as Setter).Value = background; 

, mais une exception est survenue lors:

Après un 'SetterBase' est en cours d'utilisation (étanche), il ne peut pas être modifié. Un style ne peut être modifié que lors de sa première utilisation.

+0

Cela peut être fait de façon dynamique. – Wernight

Répondre

23

Créer une brosse comme une ressource

<SolidColorBrush x:Key="MyFillBrush" Color="Pink" /> 

et se réfèrent à que dans votre style

<Style x:Key="MyShapeStyle" TargetType="Shape"> 
    <Setter Property="Fill" Value="{DynamicResource MyFillBrush}" /> 
</Style> 
... 
<!-- Then further down you may use it like this --> 
<StackPanel Width="100"> 
    <Rectangle Style="{StaticResource MyShapeStyle}" Height="50" Margin="8" /> 
    <Rectangle Style="{StaticResource MyShapeStyle}" Height="50" Margin="8" /> 
    <Ellipse Style="{StaticResource MyShapeStyle}" Height="50" Margin="8" /> 
    <Button Content="Click to change color" Click="Button_Click" Margin="8" /> 
</StackPanel> 

Maintenant à chan ge la couleur de toutes les formes qui utilisent le style « MyShapeStyle », vous pouvez effectuer les opérations suivantes à partir de votre code-behind:

private void Button_Click(object sender, RoutedEventArgs e) 
{ 
    Random r = new Random(); 
    this.Resources["MyFillBrush"] = new SolidColorBrush(Color.FromArgb(
      0xFF, 
      (byte)r.Next(255), 
      (byte)r.Next(255), 
      (byte)r.Next(255))); 
} 

Ce qui rend ce travail est le fait que vous utilisez un DynamicResource pour la référence brosse dans votre style - cela indique à WPF de surveiller cette ressource pour les changements. Si vous utilisez un StaticResource à la place, vous n'obtiendrez pas ce comportement.

+0

Une question: Puis-je passer un dynamicBrush à un userControl WPF? – serhio

+0

Je ne sais pas ce que vous entendez par "Pass" mais vous pouvez certainement le référencer à partir de votre contrôle utilisateur même s'il est défini sur un contrôle plus haut dans la hiérarchie (comme sur la fenêtre). –

+0

Cette solution peut résoudre le problème, mais elle ne répond pas exactement à la question posée – peter70

15

De MSDN:

Un style est scellé lorsqu'un autre style est basé sur il ou lorsqu'il est appliqué pour la première fois.

Au lieu de cela, vous pouvez créer un nouveau style en fonction de votre style existant, et remplacer les propriétés que vous voulez:

Style newStyle = new Style(); 
newStyle.BasedOn = originalStyle; 
newStyle.TargetType = typeof(MyLine); 
Brush blue = new SolidColorBrush(Colors.Blue); 
newStyle.Setters.Add(new Setter(Shape.FillProperty, blue)); 
newStyle.Setters.Add(new Setter(Shape.StrokeProperty, blue)); 
+0

oh ... J'ai un style avec un déclencheur ... Une ligne était rose une fois libérée, et bleue quand elle était sélectionnée ... Maintenant, j'avais besoin de changer la propriété non sélectionnée ..., donc ce n'est pas juste de le régler sur une autre couleur, le déclencheur (sélection> Bleu) ne fonctionnera plus ... – serhio

+0

mis à jour la question avec des détails .. – serhio

+0

hm ...Je suppose, si je vais détacher toutes les lignes du style, je ne serai cependant pas en mesure de le modifier, une fois utilisé ... – serhio