1

我想以两种方式动画按钮的颜色变化(基于其 IsEnabled 属性):1)当它从启用更改为禁用时 - >颜色将从白色变为黑色。2) 当它从禁用变为启用时 -> 颜色将从黑色变为白色。

我正在尝试将EventTriggerRoutedEvent一起使用,但只有一个名为 Button 的事件。已启用更改

我有一个按钮,它的 IsEnabled 属性根据逻辑状态进行更改。状态机正在工作,但我想在按钮启用或禁用时更改按钮的颜色(使用 ColorAnimation)。

最好的方法是什么?

4

2 回答 2

0

定义如下样式:

<Style x:Key="ButtonEnabledStyle" TargetType="Button">
        <Setter Property="Background" Value="White" />
        <Style.Triggers>
            <Trigger Property="IsEnabled" Value="false" >
                <Setter Property="Background" Value="Black" />
            </Trigger>
        </Style.Triggers>
    </Style>

然后将其分配给您的按钮,如下所示:

<Button Content="I'm a button" Style="{StaticResource ButtonEnabledStyle}" />
于 2012-06-19T00:05:15.237 回答
0

我希望您可以使用EventTrigger,但它们仅适用于路由事件。您将使用的事件“ IsEnabledChanged不是路由事件,因此您不能使用 EventTrigger。但是,还有另一种方法,您可以使用VisualStateManager并为禁用和正常状态提供您自己的动画。

您可以在代码隐藏中执行动画,而不是使用 VisualStateManager,并且可能您可以声明自己的自定义RoutedEvent。我的解决方案使用 VisualStateManager,其优点是它完全在 XAML 中执行。

要使用 VisualStateManager,您将使用ControlTemplate创建一个样式,我的研究还没有发现任何其他方式。这需要您构建按钮的大部分显示功能。这是我的示例的启用和禁用状态的屏幕截图:

ScreenShot.jpg![显示启用和禁用状态的屏幕截图

为了模仿正常的按钮外观,我使用了两个矩形,一个在另一个之上,作为按钮的外观。看左上角:你可以看到按钮的深灰色顶部,它来自我的一个矩形,黑色底部来自我的另一个矩形。右侧的禁用外观使用相同的两个矩形,但动画将颜色更​​改为 White 和 WhiteSmoke。我为每个矩形提供一个ColorAnimation 。

这是使用 VisualStateManager 的样式:

<Window.Resources>
    <Style TargetType="Button" x:Key="AnimatedStyle" >
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <!-- Define our button's border. Note that
                         the text color is inherited by child 
                         elements, that is we give it a name, so 
                         we can target it with the animation -->
                    <Border BorderBrush="Black" BorderThickness="1" 
                            CornerRadius="2" 
                            TextBlock.Foreground="WhiteSmoke" 
                            Name="theBorder">
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition />
                                <RowDefinition />
                            </Grid.RowDefinitions>

                            <!-- To match the appearance of a typical button, 
                                 we use two rectangles -->
                            <Rectangle Name="topBackground" Fill="DarkGray"/>
                            <Rectangle Grid.Row="1" Name="bottomBackground" 
                                       Fill="Black" />

                             <!-- The content presenter shows the 
                                  button's text -->
                            <ContentPresenter Grid.RowSpan="2" 
                                      VerticalAlignment="Center" 
                                      HorizontalAlignment="Center" />
                        </Grid>
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup Name="CommonStates">

                                <!-- Here is where we define 
                                    the disable animation -->
                                <VisualState Name="Disabled">
                                    <Storyboard>
                                        <ColorAnimation 
                                              Storyboard.TargetName="topBackground"
                                              Storyboard.TargetProperty="(Rectangle.Fill).(Color)"
                                              To="White" Duration="0:0:.5" />
                                        <ColorAnimation 
                                              Storyboard.TargetName="bottomBackground"
                                              Storyboard.TargetProperty="(Rectangle.Fill).(Color)"
                                              To="WhiteSmoke" Duration="0:0:0.5" />
                                        <ColorAnimation 
                                              Storyboard.TargetName="theBorder"
                                              Storyboard.TargetProperty="(TextBlock.Foreground).(Color)"
                                              To="Gray" Duration="0:0:0.5" />
                                    </Storyboard>
                                </VisualState>

                                <!-- Here is where the enabled animation 
                                     is defined -->
                                <VisualState Name="Normal">
                                    <Storyboard>
                                        <ColorAnimation 
                                              Storyboard.TargetName="topBackground"
                                              Storyboard.TargetProperty="(Rectangle.Fill).Color"
                                              To="DarkGray" Duration="0:0:0.5" />
                                        <ColorAnimation 
                                              Storyboard.TargetName="bottomBackground"
                                              Storyboard.TargetProperty="(Rectangle.Fill).(Color)"
                                              To="Black" Duration="0:0:0.5" />
                                        <ColorAnimation 
                                              Storyboard.TargetName="theBorder"
                                              Storyboard.TargetProperty="(TextBlock.Foreground).Color"
                                              To="WhiteSmoke" Duration="0:0:0.5" />
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

下面是一些 XAML 来利用该样式并演示实际动画:

<Grid>
     <!--The button uses the style from above. Note that we control 
         whether it is enabled by binding the Enabled property to the checkbox's 
         property 'IsChecked', that way we don't need
         any code-behind -->
    <Button Content="Test Button" Name="btnTest" 
            IsEnabled="{Binding ElementName=chkEnabled,Path=IsChecked}" 
            Height="30" Margin="5" 
            Click="btnTest_Click"
            Style="{StaticResource AnimatedStyle}" />

    <CheckBox Grid.Column="1" Content="Enable Button" 
              Name="chkEnabled" IsChecked="True" VerticalAlignment="Center" />

    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition Width="auto" />
    </Grid.ColumnDefinitions>
</Grid>

最后,只是为了证明按钮确实被禁用/启用,这里是整个代码隐藏(除了样板代码),通过单击按钮触发,但仅在启用时:

    private void btnTest_Click(object sender, RoutedEventArgs e) {
        MessageBox.Show("You clicked the button, it must be enabled.");
    }
于 2014-05-14T04:46:21.387 回答