【问题标题】:Change a style dynamically in WPF在 WPF 中动态更改样式
【发布时间】:2013-05-17 20:25:55
【问题描述】:

有没有办法在 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>
  1. 稍后,我需要更改 Pink 颜色,例如 Green,并且所有样式为 MyLineStyleKey 的行都变为绿色。一条线在释放时为粉红色,在选择时为蓝色...现在,我需要更改未选择的属性(粉红色到绿色)...,所以这不仅仅是将其设置为其他颜色,触发器(选择>蓝色)将不再工作......这可能吗?怎么样?

  2. 是否可以绑定到样式中的粉红色,例如按钮背景,以反映当前使用的样式颜色?

编辑:
对于 1,我尝试过:

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

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

但是发生了异常:

在使用“SetterBase”之后 (密封),不能修改。

【问题讨论】:

  • 这可以动态完成。

标签: wpf styles


【解决方案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,则不会出现此行为。

【讨论】:

  • 一个问题:我可以将 dynamicBrush 传递给 WPF userControl 吗?
  • 我不知道你所说的“通过”是什么意思,但你当然可以从你的用户控件中引用它,即使它是在层次结构中更高的控件上定义的(比如在窗口上)。
  • 此解决方案可能会解决问题,但它不能准确回答所提出的问题
【解决方案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));

【讨论】:

  • 哦...我有一个带触发器的样式...释放时一条线是粉红色,选择时是蓝色...现在,我需要更改未选择的属性...,所以这不仅仅是将其设置为其他颜色,触发器(选择>蓝色)将不再起作用......
  • hm...我想,如果我将所有线条从样式中分离出来,我将无法修改它,一旦使用...
  • 这是正确的解决方案,可以准确回答所提出的问题
猜你喜欢
  • 2020-03-27
  • 1970-01-01
  • 2017-12-03
  • 2013-02-16
  • 1970-01-01
  • 1970-01-01
  • 2014-12-04
  • 2021-12-26
  • 1970-01-01
相关资源
最近更新 更多