【问题标题】:How can I change an elements style at runtime?如何在运行时更改元素样式?
【发布时间】:2009-12-10 01:09:27
【问题描述】:

我有一个元素和多个样式,如何在运行时以编程方式或通过 XAML 绑定在样式之间切换。

<Rectangle x:Name="fixtureControl" Style="{DynamicResource FixtureStyle_Fast}">

<!-- In the style resources. -->
<Style x:Key="FixtureStyle_Fast" TargetType="{x:Type Shape}">
    <Setter Property="Stroke" Value="Black"/>
    <Setter Property="StrokeThickness" Value="20"/>
</Style>

<Style x:Key="FixtureStyle_Good" TargetType="{x:Type Shape}">
    <Setter Property="Effect">
        <Setter.Value>
            <DropShadowEffect Opacity=".9"
                              Direction="-90"
                              RenderingBias="Performance"
                              BlurRadius="50"
                              ShadowDepth="10" />
        </Setter.Value>
    </Setter>
</Style>

<Style x:Key="FixtureStyle_Best" TargetType="{x:Type Shape}">
    <Setter Property="Effect">
        <Setter.Value>
            <DropShadowEffect Opacity=".9"
                              Direction="-90"
                              RenderingBias="Quality"
                              BlurRadius="50"
                              ShadowDepth="10" />
        </Setter.Value>
    </Setter>
</Style>

然后我有一些处理更改样式的单选按钮

private void RadioButton_Click(object sender, RoutedEventArgs e) {
    if (e.Source == rdoQualityBest) {
        fixtureControl.Style = FindResource("FixtureStyle_Best") as Style;
    } else if (e.Source == rdoQualityGood) {
        fixtureControl.Style = FindResource("FixtureStyle_Good") as Style;
    } else {
        fixtureControl.Style = FindResource("FixtureStyle_Fast") as Style;
    }
}

但是,这会将样式应用于元素,而不是替换它,所以如果我应用 Fast then Quality,我会同时获得边框和阴影。

【问题讨论】:

  • 我无法真正为您提供答案,但我相信如果您想通过 XAML 绑定处理样式,您应该查看触发器。这是一篇可能有用的 CodeProject 文章:codeproject.com/KB/WPF/codeVsXAML.aspx

标签: c# wpf xaml styles


【解决方案1】:

过去,类似的方法对我有用(纯 XAML 解决方案):

<!-- Styles 1-4 defined somewhere else on your page -->
<ComboBox Name="AvailableStyles">
    <ComboBoxItem Tag="{x:Null}" IsSelected="True">None</ComboBoxItem>
    <ComboBoxItem Tag="{StaticResource Style1}">1</ComboBoxItem>
    <ComboBoxItem Tag="{StaticResource Style2}">2</ComboBoxItem>
    <ComboBoxItem Tag="{StaticResource Style3}">3</ComboBoxItem>
    <ComboBoxItem Tag="{StaticResource Style4}">4</ComboBoxItem>
</ComboBox>

<Button Content="Button" Style="{Binding ElementName=AvailableStyles, Path=SelectedItem.Tag}"/>
<CheckBox Content="Check Box" Style="{Binding ElementName=AvailableStyles, Path=SelectedItem.Tag}"/>
<RadioButton Content="Radio Button"Style="{Binding ElementName=AvailableStyles, Path=SelectedItem.Tag}"/>

希望这会有所帮助!

【讨论】:

  • 您知道我几乎做到了这一点,但假设它的行为与我通过代码更改的方式相同。我很惊讶这实际上有效,并且很想知道为什么它不能通过简单地应用样式来通过代码工作。了不起的 Pwninstein,效果很好 :)
  • 我不是 100% 确定为什么代码方法的工作方式不同,但我认为这是因为当您通过 Binding 设置样式时,它知道在样式之间切换时如何“撤消”所有内容。只是一个猜测。不管怎样,很高兴有帮助!
【解决方案2】:

对我来说很好用

这是我的代码:

在 .xaml 中

    <Window.Resources>
    <Style x:Key="FixtureStyle_Fast" TargetType="{x:Type Shape}">
        <Setter Property="Stroke" Value="Black"/>
        <Setter Property="StrokeThickness" Value="20"/>
    </Style>

    <Style x:Key="FixtureStyle_Good" TargetType="{x:Type Shape}">
        <Setter Property="Stroke" Value="Red"/>
        <Setter Property="StrokeThickness" Value="20"/>
    </Style>

    <Style x:Key="FixtureStyle_Best" TargetType="{x:Type Shape}">
        <Setter Property="Stroke" Value="Blue"/>
        <Setter Property="StrokeThickness" Value="20"/>
    </Style>
</Window.Resources>
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>
     <Rectangle x:Name="fixtureControl" Style="{DynamicResource FixtureStyle_Fast}"/>
    <StackPanel Grid.Column="1">
    <RadioButton Name="rdoQualityBest" Content="Best" Click="RadioButton_Click" />
    <RadioButton Name="rdoQualityGood" Content="Good" Click="RadioButton_Click" />
    <RadioButton Name="rdoQualityFast" Content="Fast" Click="RadioButton_Click" />
    </StackPanel>
</Grid>

在 .xaml.cs 中

private void RadioButton_Click(object sender, RoutedEventArgs e)
{
    if (e.Source == rdoQualityBest)
    {
        fixtureControl.Style = FindResource("FixtureStyle_Best") as Style;
    }
    else if (e.Source == rdoQualityGood)
    {
        fixtureControl.Style = FindResource("FixtureStyle_Good") as Style;
    }
    else
    {
        fixtureControl.Style = FindResource("FixtureStyle_Fast") as Style;
    }
}

【讨论】:

  • 在您的示例中的所有样式中,您都设置了相同的属性,因此在应用新样式时它会被覆盖。对我来说似乎发生的事情是,如果我有一种只设置“Stroke”属性的样式,而另一种只填充“StrokeThickness”的样式,那么只会应用该属性,它不会重置其他属性(s )。
猜你喜欢
  • 2011-06-05
  • 2016-03-20
  • 1970-01-01
  • 2022-08-19
  • 2011-10-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多