如何在像google按钮这样的wpf按钮周围创建阴影下拉效果

时间:2012-09-28 07:14:56

标签: wpf button styles shadow

我正在尝试在wpf中创建一个google按钮。我找到了以下链接,指定了谷歌的按钮css样式

Google button css style

现在我也搜索了网络,发现这种风格类似于谷歌的按钮

<Style x:Key="GoogleGreyButton" TargetType="{x:Type Button}">
    <Setter Property="Background" Value="#FFF5F5F5"/>
    <Setter Property="BorderBrush" Value="#FFDCDCDC"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="Foreground" Value="#FF666666"/>
    <Setter Property="FontWeight" Value="Bold"/>
    <Setter Property="FontSize" Value="11"/>
    <Setter Property="FontFamily" Value="Arial"/>
    <Setter Property="HorizontalContentAlignment" Value="Center"/>
    <Setter Property="VerticalContentAlignment" Value="Center"/>
    <Setter Property="Padding" Value="8,7"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Border Name="border" 
                    BorderThickness="{TemplateBinding BorderThickness}"
                    Padding="{TemplateBinding Padding}" 
                    BorderBrush="{TemplateBinding BorderBrush}" 
                    CornerRadius="1" 
                    Background="{TemplateBinding Background}">
                    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                                  VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>

                </Border>

                <ControlTemplate.Triggers>
                    <!--TODO: Set the right colors-->
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter TargetName="border" Property="BorderBrush" Value="#FFC6C6C4" />
                        <Setter Property="Foreground" Value="#FF020202" />
                    </Trigger>
                    <Trigger Property="IsPressed" Value="True">
                       ` <!--Some setters here--> `

                    </Trigger>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Foreground" Value="#ADADAD"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<Trigger Property="IsPressed" Value="True">部分我需要产生一些阴影效果,如上面的Google button css style,我可以知道如何实现这一点吗?

2 个答案:

答案 0 :(得分:19)

您可以通过更改一些BorderThickness来产生阴影效果。尝试这样的事情:

<Trigger Property="IsMouseOver" Value="True">
    <Setter TargetName="border" Property="BorderBrush" Value="DarkGray" />
    <Setter Property="Foreground" Value="Black" />
    <Setter Property="BorderThickness" Value="1,1,2,2" />
</Trigger>

请注意,这样做可能会使您的布局陷入困境,因为它会改变按钮的总宽度和高度,因此当它悬停按钮时,周围的其他控件可能会“晃动”一点点。

如果您想要使用正确的投影,可以在按钮上添加投影,如下所示:

<Button>
    <Button.BitmapEffect>
        <DropShadowBitmapEffect Color="Black" Direction="320" Softness="1" ShadowDepth="10" Opacity="0.5" />
    </Button.BitmapEffect>
</Button>

修改

正如MrDosu评论的那样,BitMapEffect已被弃用,因此您应该使用Effect代替。

以下是使用效果的示例:

<Trigger Property="IsMouseOver" Value="True">
    <Setter TargetName="border" Property="BorderBrush" Value="DarkGray" />
    <Setter Property="Foreground" Value="Black" />
    <Setter Property="Button.Effect">
        <Setter.Value>
            <DropShadowEffect Color="Black" Direction="320" ShadowDepth="3" BlurRadius="5" Opacity="0.5" />
        </Setter.Value>
    </Setter>
</Trigger>

答案 1 :(得分:0)

如果要实现实质阴影(所谓的 elevation ),则可以使用以下代码:

public static class UI
{

    public static readonly DependencyProperty ElevationProperty = DependencyProperty.RegisterAttached("Elevation", typeof(double), typeof(UI), new FrameworkPropertyMetadata(default(double), FrameworkPropertyMetadataOptions.AffectsRender, null, OnElevationChanged));

    public static double GetElevation(this UIElement element) => element.GetValue(ElevationProperty) as double? ?? default;

    public static void SetElevation(this UIElement element, double elevation) => element.SetValue(ElevationProperty, elevation);

    private static object OnElevationChanged(DependencyObject d, object value)
    {
        if (d is UIElement element && value is double elevation)
            if (elevation == 0)
                element.Effect = null;
            else
            {
                Effect e = CreateElevation(elevation, element.Effect);
                if (e != null)
                    element.Effect = e;
            }
        return value;
    }

    private static Effect CreateElevation(double elevation, Effect source)
    {
        void MixShadows(DropShadowEffect nearest, DropShadowEffect matched, double balance)
        {
            matched.BlurRadius = matched.BlurRadius * (1 - balance) + nearest.BlurRadius * balance;
            matched.ShadowDepth = matched.ShadowDepth * (1 - balance) + nearest.ShadowDepth * balance;
        }
        DropShadowEffect[] shadows = new DropShadowEffect[]
        {
            new DropShadowEffect()
            {
                BlurRadius = 5,
                ShadowDepth = 1
            },
            new DropShadowEffect()
            {
                BlurRadius = 8,
                ShadowDepth = 1.5
            },
            new DropShadowEffect()
            {
                BlurRadius = 14,
                ShadowDepth = 4.5
            },
            new DropShadowEffect()
            {
                BlurRadius = 25,
                ShadowDepth = 8
            },
            new DropShadowEffect()
            {
                BlurRadius = 35,
                ShadowDepth = 13
            }
        };
        elevation = Math.Max(0, elevation / 12 * shadows.Length - 1);
        int prevIndex = (int)Math.Floor(elevation), index = (int)elevation, nextIndex = (int)Math.Ceiling(elevation);
        double approx = elevation - index;
        DropShadowEffect shadow = shadows[index];
        if (approx != 0)
            MixShadows(approx < 0 ? shadows[prevIndex] : shadows[nextIndex], shadow, Math.Abs(approx));
        bool modify = false;
        if (source is DropShadowEffect sourceShadow)
        {
            sourceShadow.BlurRadius = shadow.BlurRadius;
            sourceShadow.ShadowDepth = shadow.ShadowDepth;
            shadow = sourceShadow;
            modify = true;
        }
        shadow.Direction = 270;
        shadow.Color = Color.FromArgb(0xAA, 0, 0, 0);
        shadow.Opacity = .42;
        shadow.RenderingBias = RenderingBias.Performance;
        return modify ? null : shadow;
    }
}

然后:

<Button local:Elevation="2">Elevated button</Button>

您可以将2到12之间的任意值设置为任何UIElement的高度。