2010-09-29 12 views
14

Czy istnieje sposób, aby zmienić (i zastosować) styl dynamicznie w WPF?Zmiana stylu dynamicznie w WPF

że mam styl zadeklarowane w 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. za chwilę, muszę zmiany kolorem Pink, do, powiedzmy Green, a wszystkie linie z stylem MyLineStyleKey stał Zielony . Linia jest różowa po zwolnieniu, a niebieska po wybraniu ... Teraz potrzebuję zmienić niezaznaczoną właściwość (od różowego do zielonego) ..., więc to nie jest tylko ustawienie jej na inny kolor, spust (wybór> niebieski) nie będzie działać ... Czy to możliwe? W jaki sposób?

  2. Czy to możliwe, aby powiązać z kolorem różowym w stylu, powiedzmy, na tle przycisku, który będzie odzwierciedlał aktualnie używany kolor stylu?

Edycja:
Na że próbował:

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

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

lecz wyjątkiem wystąpił:

Po 'SetterBase' jest używany (zamknięte), to nie można modyfikować.

+0

Można to zrobić dYnamicznie. – Wernight

Odpowiedz

23

Tworzenie pędzla jako zasób

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

i odnoszą się do w Twoim stylu:

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

Teraz, aby zmienić ge kolor wszystkich kształtach, które używają „MyShapeStyle” styl, można wykonać następujące czynności z kodu z opóźnieniem:

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))); 
} 

Tym, co sprawia, że ​​ta praca jest fakt, że można użyć DynamicResource na odniesienie szczotkowym w twoim stylu - to mówi WPF, żeby monitorowała ten zasób pod kątem zmian. Jeśli użyjesz zamiast tego opcji StaticResource, nie uzyskasz takiego zachowania.

+0

Pytanie: Czy mogę przekazać dynamicznego pędzla? do kontrolki użytkownika WPF? – serhio

+0

Nie wiem, co masz na myśli mówiąc "Przełęcz", ale na pewno możesz odwołać się do niego z poziomu kontroli użytkownika, nawet jeśli jest on zdefiniowany na kontrolerze wyżej w hierarchii (jak w oknie). –

+0

To rozwiązanie może rozwiązać problem, ale nie odpowiada dokładnie na zadane pytanie – peter70

15

Styl można zmodyfikować tylko przed pierwszym użyciem. Z MSDN:

Styl jest zapieczętowany, gdy inny styl jest na nim oparty lub kiedy jest stosowany po raz pierwszy.

Zamiast tego, można utworzyć nowy styl w oparciu o swoim stylu istniejącego i nadpisać właściwości chcesz:

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 ... Mam styl z wyzwalaczem ... Linia była różowa po wydaniu i niebieska po wybraniu ... Teraz, musiałem zmienić niezaznaczoną właściwość ..., więc to nie jest ustawienie jej tylko inny kolor, spust (wybór> niebieski) nie będzie już działać ... – serhio

+0

zaktualizował pytanie o szczegóły .. – serhio

+0

hm ...Przypuszczam, że jeśli odetnę wszystkie linie od tego stylu, nie będę mógł go zmodyfikować, raz użyty ... – serhio