Animating SolidColorBrush in Background

烈酒焚心 提交于 2020-01-07 03:58:08

问题


I am trying to create a simple button style, that will change the opacity of the background from 0.0 to 1.0 on mouse over (and vice versa). I am creating a template for said button and I am binding all the properties in the template. It all works properly except the SolidColorBrush in background, that I can not bind to the template binding. I've seen some mentions of TemplateBinding not being the right one due to contexts, but I am not able to find another solution. I suspect, there might be a problem of Background being a Brush and I need just a Color component of that brush, but I am not able to obtain it.

The obvious override is to create two template styles with two different colors (which works), but I would like to avoid such hard-coding and copy-paste. What I would like to have is an option to specify Background property on Button, that would be used in SolidColorBrush and then the opacity would do the rest.

<Style TargetType="{x:Type Button}" x:Key="WindowButtonStyle">
    <Setter Property="Width" Value="46" />
    <Setter Property="Height" Value="32" />
    <Setter Property="BorderThickness" Value="0" />
    <Setter Property="VerticalAlignment" Value="Center" />

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
                    <Border.Background>
                        <SolidColorBrush x:Name="ButtonBackgroundBrush" Color="???" Opacity="0.0" />
                    </Border.Background>
                    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}" />
                </Border>
                <ControlTemplate.Resources>
                    <Storyboard x:Key="MouseOverAnimation">
                        <DoubleAnimation Storyboard.TargetName="ButtonBackgroundBrush" Storyboard.TargetProperty="Opacity" To="1.0" Duration="0:0:0.15" />
                    </Storyboard>
                    <Storyboard x:Key="MouseOutAnimation">
                        <DoubleAnimation Storyboard.TargetName="ButtonBackgroundBrush" Storyboard.TargetProperty="Opacity" To="0.0" Duration="0:0:0.15" />
                    </Storyboard>
                </ControlTemplate.Resources>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Trigger.EnterActions>
                            <BeginStoryboard Storyboard="{StaticResource MouseOverAnimation}" />
                        </Trigger.EnterActions>
                        <Trigger.ExitActions>
                            <BeginStoryboard Storyboard="{StaticResource MouseOutAnimation}" />
                        </Trigger.ExitActions>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Then, the button is used like this:

<Button x:Name="MinimizeButton" Style="{StaticResource WindowButtonStyle}" Click="MinimizeButton_Click" Background="Green">
    <Image Source="../Resources/WindowButtons/Images/win-minimize.png" Width="12" Height="12"></Image>
</Button>

Added Background="Green" property setting to test it, but did not worked.


回答1:


You could use a TemplateBinding to bind the Background property of the Border to the Background of the Button and then animate the Opacity property of the SolidColorBrush like this:

<Style TargetType="{x:Type Button}" x:Key="WindowButtonStyle">
    <Setter Property="Width" Value="46" />
    <Setter Property="Height" Value="32" />
    <Setter Property="BorderThickness" Value="0" />
    <Setter Property="VerticalAlignment" Value="Center" />

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"
                                Background="{TemplateBinding Background}">
                    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}" />
                </Border>
                <ControlTemplate.Resources>
                    <Storyboard x:Key="MouseOverAnimation">
                        <DoubleAnimation Storyboard.TargetName="border" Storyboard.TargetProperty="Background.(SolidColorBrush.Opacity)" To="1.0" Duration="0:0:0.15" />
                    </Storyboard>
                    <Storyboard x:Key="MouseOutAnimation">
                        <DoubleAnimation Storyboard.TargetName="border" Storyboard.TargetProperty="Background.(SolidColorBrush.Opacity)" To="0.0" Duration="0:0:0.15" />
                    </Storyboard>
                </ControlTemplate.Resources>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Trigger.EnterActions>
                            <BeginStoryboard Storyboard="{StaticResource MouseOverAnimation}" />
                        </Trigger.EnterActions>
                        <Trigger.ExitActions>
                            <BeginStoryboard Storyboard="{StaticResource MouseOutAnimation}" />
                        </Trigger.ExitActions>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>



回答2:


Answering my own, as always - you figure out the solution just after you post on S/O. So I hope it will help someone:

...
                    <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
                        <Border.Background>
                            <!-- ReSharper disable once Xaml.BindingWithContextNotResolved -->
                            <SolidColorBrush x:Name="ButtonBackgroundBrush" Color="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Background.Color}" Opacity="0.0" />
                        </Border.Background>
                        <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}" />
                    </Border>
...

I've included the ReSharper disable as well, because the warning form ReSharper was what kept me from trying this one - and desperation forced me to try it anyway.



来源:https://stackoverflow.com/questions/43654097/animating-solidcolorbrush-in-background

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!