WPF 使用混合更改样式

Posted

技术标签:

【中文标题】WPF 使用混合更改样式【英文标题】:WPF Change style using blend 【发布时间】:2016-09-23 07:32:02 【问题描述】:

是否可以仅使用 xaml 通过混合触发器更改样式属性?例如,在第一个RadioButton 上触发事件Checked 之后,在Visible 上更改Visibility 样式的FirstStyle 属性。

<Window x:Class="switch_style.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:Interactivity="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
        xmlns:Interactions="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <Style x:Key="FirstStyle" TargetType="Label" x:Name="block">
            <Setter Property="Visibility" Value="Collapsed"/>
        </Style>
    </Window.Resources>
    <Grid>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="auto"></RowDefinition>
                <RowDefinition Height="auto"></RowDefinition>
                <RowDefinition Height="auto"></RowDefinition>
            </Grid.RowDefinitions>
            <StackPanel Orientation="Horizontal">
                <Label Style="DynamicResource FirstStyle">First</Label>
                <Label>Second</Label>
                <Label>Third</Label>
            </StackPanel>
            <StackPanel Grid.Row="2" Orientation="Vertical">
                <RadioButton Width="60" HorizontalAlignment="Left" Content="First">
                    <Interactivity:Interaction.Triggers>
                        <Interactivity:EventTrigger EventName="Checked">
                            <Interactions:ChangePropertyAction TargetName="Binding block"  PropertyName="Visibility" Value="Visible"/>
                        </Interactivity:EventTrigger>
                    </Interactivity:Interaction.Triggers>
                </RadioButton>
                <RadioButton Width="60" HorizontalAlignment="Left">Second</RadioButton>
                <RadioButton Width="60" HorizontalAlignment="Left">Third</RadioButton>
            </StackPanel>
        </Grid>
    </Grid>
</Window>

【问题讨论】:

如果您试图根据 RadioButton 是否被选中来使标签可见/不可见,那么为什么不直接将 Label 的可见性绑定到 RadioButton IsChecked 属性呢? @sthotakura,也许这是个好主意。如果我应该使用一种样式并且在其中我应该绑定标签的可见性以检查按钮中的属性。但是如何将样式中的 Value=Binding ... 绑定到控件属性? 嗯.. 这很棘手。请看我的回答。 【参考方案1】:

Style 对象在应用于Control 的那一刻就变得不可变。如果此Style 尚未应用,是的,您可以更改它。

因此,您应该创建 2 个单独的 Styles 并根据 Trigger 选择一个 Style

【讨论】:

【参考方案2】:

因为,我不太清楚你为什么只想在 XAML 中做,但这是我的尝试,它有效。

我已将您的样式更新为以下内容:

  <Style x:Key="FirstStyle" TargetType="Label">
     <Setter Property="Visibility" Value="Collapsed"/>
     <Style.Triggers>
        <DataTrigger Binding="Binding IsChecked" Value="True">
           <Setter Property="Visibility" Value="Visible"/>
        </DataTrigger>
     </Style.Triggers>
  </Style>

然后,我将Labels 上的DataContext 设置为对应的RadioButtons。这是完整的 XAML:

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
   <Page.Resources>
      <Style x:Key="FirstStyle" TargetType="Label">
         <Setter Property="Visibility" Value="Collapsed"/>
         <Style.Triggers>
            <DataTrigger Binding="Binding IsChecked" Value="True">
               <Setter Property="Visibility" Value="Visible"/>
            </DataTrigger>
         </Style.Triggers>
      </Style>
   </Page.Resources>
   <Grid>
      <Grid>
         <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="auto"/>
         </Grid.RowDefinitions>
         <StackPanel Orientation="Horizontal">
            <Label Content="First" DataContext="Binding ElementName=radioButton1" Style="DynamicResource FirstStyle"/>
            <Label Content="Second" DataContext="Binding ElementName=radioButton2" Style="DynamicResource FirstStyle"/>
            <Label Content="Third" DataContext="Binding ElementName=radioButton3" Style="DynamicResource FirstStyle"/>
         </StackPanel>
         <StackPanel Grid.Row="2" Orientation="Vertical">
            <RadioButton
               x:Name="radioButton1"
               Width="60"
               HorizontalAlignment="Left"
               Content="First"/>
            <RadioButton
               x:Name="radioButton2"
               Width="60"
               HorizontalAlignment="Left"
               Content="Second"/>
            <RadioButton
               x:Name="radioButton3"
               Width="60"
               HorizontalAlignment="Left"
               Content="Third"/>
         </StackPanel>
      </Grid>
   </Grid>
</Page>

如果我们可以将 RadioButtonIsCheckedLabels Visibility 绑定到支持 ViewModel 上的相同属性,可能会更容易。

解决这个问题的另一种方法是@AnjumSKhan 的回答。

【讨论】:

以上是关于WPF 使用混合更改样式的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 WPF 按钮的参数或绑定来更改 XAML 样式中的 fa 图标

WPF:ContentPresenter 根据样式的位置意外更改前景

WPF - 根据项目模板更改组合框样式

WPF 样式:如何更改触发器中的 GradientStop 颜色

WPF 点击按钮时更改按钮样式界面效果的 XAML 实现方法

如何从 ViewModel 更改样式属性?