如何在 wpf 按钮(如 google 按钮)周围创建阴影效果

     2023-02-22     141

关键词:

【中文标题】如何在 wpf 按钮(如 google 按钮)周围创建阴影效果【英文标题】:How to create a shadow drop effect around a wpf button like the google button 【发布时间】:2012-09-20 01:27:54 【问题描述】:

我正在尝试在 wpf 中创建一个 google 按钮。我发现以下链接指定了 google 的按钮 css 样式

Google button css style

我现在也在网上搜了一下,发现这个样式很像google的按钮

<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>

&lt;Trigger Property="IsPressed" Value="True"&gt; 部分我需要像上面的Google button css style 那样产生一些阴影效果,请问我该如何实现?

【问题讨论】:

您应该考虑使用表达式混合来创建您的 wpf UI。它很好地满足您的需求 链接失效了。 【参考方案1】:

您可以通过更改 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。

这是一个使用 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>

【讨论】:

在 .NET Framework 4 或更高版本中,BitmapEffect 类已过时。如果您尝试使用 BitmapEffect 类,您将得到一个过时的异常。 BitmapEffect 类的非过时替代品是 Effect 类。在大多数情况下,Effect 类的速度要快得多。 还有一个问题,单击按钮后鼠标左键向上的触发属性是什么?我希望按钮在单击后返回IsEnabled 状态。 尝试使用 ToggleButton,BorderThickness 不起作用,但 DropShadowEffect 起作用。【参考方案2】:

过去,我是这样实现材质提升的:

public static class UI

    private static readonly DropShadowEffect[] sShadows = new[]
    
        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
        
    ;

    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 dependencyObject, object value)
    
        if (dependencyObject is UIElement element && value is double elevation)
        
            if (elevation == 0)
            
                element.Effect = null;
            
            else
            
                var effect = CreateElevation(elevation, element.Effect);

                if (effect != null)
                    element.Effect = effect;
            
        

        return value;
    

    private static void MixShadows(DropShadowEffect target, DropShadowEffect other, double balance)
    
        target.BlurRadius = target.BlurRadius * (1 - balance) + other.BlurRadius * balance;
        target.ShadowDepth = target.ShadowDepth * (1 - balance) + other.ShadowDepth * balance;
    

    private static Effect CreateElevation(double elevation, Effect source)
    
        if (elevation < 0 || elevation > 12)
            throw new ArgumentOutOfRangeException("Elevation must be between 0 and 12.", nameof(elevation));

        elevation = Math.Max(0, elevation / 12 * shadows.Length - 1);

        var shadows = sShadows;
        var prevIndex = (int)Math.Floor(elevation);
        var index = (int)elevation;
        var nextIndex = (int)Math.Ceiling(elevation);
        var approx = elevation - index;
        var shadow = shadows[index];
        var modify = false;

        if (approx != 0)
            MixShadows(shadow, approx < 0 ? shadows[prevIndex] : shadows[nextIndex], Math.Abs(approx));

        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 的高度。

【讨论】:

如何在iOS中显示大按钮而不单击按钮(单击该按钮周围的区域)

】如何在iOS中显示大按钮而不单击按钮(单击该按钮周围的区域)【英文标题】:Howtoshowbigbuttonwithoutclickingbutton(clickingareaaroundthatbutton)iniOS【发布时间】:2012-09-0602:59:46【问题描述】:我为键盘做了很多按钮。当我单击一个按钮... 查看详情

设计一个圆形按钮,周围有垂直线

...条,如粗略的想法所示picture在这里。请查看并分享您对如何在Android、iOS或Xamarin中进行设计的想法。谢谢【问题讨论】:发帖前请阅读HowtoAsk。对于iOS检查* 查看详情

如何为 WPF 中的工具栏按钮创建热键?

】如何为WPF中的工具栏按钮创建热键?【英文标题】:HowdoyoucreatehotkeysfortoolbarbuttonsinWPF?【发布时间】:2012-07-1101:48:51【问题描述】:在WPF中,您可以按如下方式制作按钮:<ButtonName="Foo"Content="_Foo"/>“F”前的下划线将F键与Fo... 查看详情

如何在 NSTexturedSquareBezelStyle 按钮周围绘制边框

】如何在NSTexturedSquareBezelStyle按钮周围绘制边框【英文标题】:HowtodrawaborderaroundanNSTexturedSquareBezelStylebutton【发布时间】:2015-04-2219:03:28【问题描述】:前几天我注意到我的一个网页看起来很丑。页面上的按钮看起来像totallydiffere... 查看详情

如何在单击时消除按钮周围的焦点

】如何在单击时消除按钮周围的焦点【英文标题】:Howtoremovefocusaroundbuttonsonclick【发布时间】:2013-10-0321:27:11【问题描述】:单击后,我的按钮周围都有一个突出显示。这是在Chrome中。<buttonclass="btnbtn-primarybtn-block"><spanclas... 查看详情

如何在wpf中窗口栏上添加按钮?

如何在WPF中窗口栏上添加按钮,就是和最大化最小化按钮一起放一个自定义的按钮参考技术A没事,双击一个菜单栏应该就可以了. 查看详情

如何在 UI 按钮/文本标签中的字母周围制作边框?

】如何在UI按钮/文本标签中的字母周围制作边框?【英文标题】:HowtomakeaborderaroundaletterinUIButton/TextLabel?【发布时间】:2014-04-1306:37:57【问题描述】:我已经尝试过了40分钟,但我仍然无法在出现的文本周围添加边框,它仍然是... 查看详情

如何自定义警报对话框按钮,如 Google Photos App 中的

】如何自定义警报对话框按钮,如GooglePhotosApp中的【英文标题】:HowtocustomizeAlertDialogbuttonslikeinGooglePhotosApp【发布时间】:2019-05-2900:15:54【问题描述】:如何实现这样的警报对话框按钮样式:我是否必须创建自定义“对话框”或... 查看详情

如何在WPF中的可用宽度内将按钮放入一行

】如何在WPF中的可用宽度内将按钮放入一行【英文标题】:HowtofitbuttonsintoarowwithinavailablewidthinWPF【发布时间】:2022-01-1403:05:41【问题描述】:这是我的代码。我是WindowPresentationFoundation(WPF)的新手,我有一个一行一列的网格。我有... 查看详情

如何在 WPF 中删除鼠标悬停时的按钮发光

】如何在WPF中删除鼠标悬停时的按钮发光【英文标题】:HowtoremoveGlowofButtononMousehoverinWPF【发布时间】:2013-08-0922:33:53【问题描述】:我在WPF中使用了一个简单的按钮。我已经在背景上放置了按钮的图像。我的问题是,当我将鼠... 查看详情

在 WPF 中设置按钮 FlatStyle

...:24:11【问题描述】:我刚刚学习了WPF中的样式和控件模板如何影响按钮的外观,我正在尝试设置Button的FlatStyle,在我看到的资源中我找不到任何可以告诉我如何做到这一点的信息,在Windows窗体中这是通过FlatStyle=Flat设置的。如何... 查看详情

如何在 WPF 中禁用按钮上的 MouseOver 效果?

】如何在WPF中禁用按钮上的MouseOver效果?【英文标题】:HowdoyoudisableMouseOvereffectsonaButtoninWPF?【发布时间】:2010-11-1612:04:07【问题描述】:我正在尝试在WPF中禁用按钮上的MouseOver效果,或者至少改变它的颜色。我正在使用以下样... 查看详情

wpf中如何彻底去除按钮边框?

】wpf中如何彻底去除按钮边框?【英文标题】:Howdoyoucompletelyremovethebuttonborderinwpf?【发布时间】:2010-11-0300:06:09【问题描述】:我正在尝试创建一个包含图像且没有边框的按钮-就像Firefox工具栏按钮在您将鼠标悬停在它们上方并... 查看详情

如何在 WPF 中停止方法(通过按钮单击触发)

】如何在WPF中停止方法(通过按钮单击触发)【英文标题】:Howtostopamethod(triggeredbybuttonclick)inWPF【发布时间】:2021-06-1009:58:03【问题描述】:我的WPF中有一个私有asyncvoidButton_Click方法,它运行一个非常复杂的SQL查询,可以运行几... 查看详情

如何防止 WPF 按钮在单击后保持突出显示?

】如何防止WPF按钮在单击后保持突出显示?【英文标题】:HowdoIpreventWPFbuttonsfromremaininghighlightedafterbeingclicked?【发布时间】:2011-08-2211:03:04【问题描述】:单击标准WPF按钮时,它会以蓝色突出显示(可能使用设置的任何Windows主题... 查看详情

如何删除焦点按钮文本周围的虚线白色边框

】如何删除焦点按钮文本周围的虚线白色边框【英文标题】:Howtoremovethedottedwhiteborderaroundfocusedbuttontext【发布时间】:2019-11-0514:52:55【问题描述】:我需要但不能删除焦点按钮文本周围的白色虚线边框。在阅读了有关“删除白色... 查看详情

如何在 wpf 中实现带有清除按钮的文本框?

】如何在wpf中实现带有清除按钮的文本框?【英文标题】:Howtoimplementatextboxwithaclearbuttoninwpf?【发布时间】:2012-11-1710:58:18【问题描述】:我有以下UserControl。这是一个TextBox和一个Button:<Grid><TextBoxGrid.Column="0"Text="BindingText... 查看详情

如何在 WPF 中的窗口标题栏上呈现按钮等?

】如何在WPF中的窗口标题栏上呈现按钮等?【英文标题】:HowtorenderbuttonsandsuchonwindowtitlebarinWPF?【发布时间】:2012-03-1006:43:41【问题描述】:我可以使用WPF的边距和变换功能将按钮移动到标题栏上。但是,当我尝试它时,该按钮... 查看详情