Динамически изменять стиль в WPF
Есть ли способ динамически изменять (и применять) стиль в WPF?
Скажем, у меня есть стиль, объявленный в 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>
-
В какой-то момент мне нужно изменить цвет Pink
, скажем Green
, а все строки со стилем MyLineStyleKey
стали зелеными. Линия розовая, когда ее отпускают, а синий - когда выбрано... Теперь мне нужно было изменить невыбранное свойство (от Pink до Green)..., так что это не просто настройка его на другой цвет, триггер (выбоp > синий ) больше не будет работать... Это возможно? Как?
-
Возможно ли привязать к розовому цвету в стиле, скажем, к фону кнопки, который будет отражать используемый в текущий момент цвет стиля?
EDIT:
Для 1 я попробовал:
Style s = (Style)this.Resources["MyLineStyleKey"];
(s.Setters[0] as Setter).Value = background;
(s.Setters[1] as Setter).Value = background;
но произошло исключение:
После использования "SetterBase" (запечатан), он не может быть изменен.
Ответы
Ответ 1
Создайте кисть в качестве ресурса
<SolidColorBrush x:Key="MyFillBrush" Color="Pink" />
и обратитесь к этому в своем стиле
<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>
Теперь, чтобы изменить цвет всех фигур, которые используют стиль "MyShapeStyle", вы можете сделать следующее из кода:
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)));
}
То, что делает эту работу, состоит в том, что вы используете DynamicResource
для ссылки на кисть в своем стиле - это говорит WPF контролировать этот ресурс для изменений. Если вместо этого вы используете StaticResource
, вы не получите этого поведения.
Ответ 2
Стиль может быть изменен только до его первого использования. Из MSDN:
Стиль запечатан, когда другой стиль основан на нем или когда он применяется в первый раз.
Вместо этого вы можете создать новый стиль на основе существующего стиля и переопределить нужные свойства:
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));