WPF:带有cornerRadius和Bevel的按钮模板看起来错误

Posted

技术标签:

【中文标题】WPF:带有cornerRadius和Bevel的按钮模板看起来错误【英文标题】:WPF: Button template w/ cornerRadius and Bevel looks wrong 【发布时间】:2010-07-29 13:40:52 【问题描述】:

我更改了一个按钮的 ControrTemplate,用 CornerRadius 和 BevelBitmpaEffect 给它一个边框。看起来足够体面,只需付出最小的努力。把它放在彩色背景上,然后问题就显现出来了。

lightangle 来自的角落有一个带有直角角的白色剪断。可能来自灯光效果,但使用cornerRadius 时非常明显。我认为我对此无能为力(除了不使用cornerRadius 等显而易见的问题)?

编辑:

这段代码应该会为你产生同样的问题

<Style x:Key="TabButtons" TargetType="Button">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Border CornerRadius="8"
                        SnapsToDevicePixels="True"
                        Name="BtnBorder"
                        Width="80"
                        Height="35"
                        BorderThickness="1"
                        BorderBrush="DarkBlue">
                    <Border.Background>

                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                            <GradientStop Color="LightBlue" Offset="0" />
                            <GradientStop Color="DarkBlue" Offset="1" />
                        </LinearGradientBrush>

                    </Border.Background>
                    <Border.BitmapEffect>
                        <BevelBitmapEffect BevelWidth="5"
                                           EdgeProfile="CurvedOut"
                                           LightAngle="135"
                                           Relief="0.1"
                                           Smoothness="1" />
                    </Border.BitmapEffect>
                    <ContentPresenter Name="BtnContent" VerticalAlignment="Center" HorizontalAlignment="Center" ContentSource="Content" />
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

例如在浅蓝色背景上使用此按钮

<Border Background="LightBlue" >
    <Button Style=StaticResource TabButtons >Test</Button>
</Border>

【问题讨论】:

【参考方案1】:

我无法想象问题究竟是什么样子,但这里有一个建议 - 尝试将受影响的按钮或整个窗口的 SnapsToDevicePixels 设置为 true。 问题可能源于默认情况下 WPF 想要进行设备独立渲染的事实。由于宽度/高度和 DPI/像素未完全对齐,这会导致控制边缘略微“溢出”到相邻像素。将 SnapsToDevicePixels 设置为 true,将强制 WPF 完全针对设备像素进行渲染,并且“出血”效果将消失...

编辑: 我尝试了您提供的代码,我猜“白色剪辑”是角落周围的白色(ish)像素? 那么这里的问题源于抗锯齿,它也减轻了角落内的像素。因为你使用了深色调,那些较亮的像素会突出,按钮看起来不太好。

我不确定这是否可以被视为错误。您可能会认为抗锯齿会对构成角落和角落外部的像素产生神奇的效果,但角落内的每个像素都应使用背景颜色着色。 再一次,这可能是设计使然,抗锯齿也必须与角落内的像素混淆,否则您将无法获得所需的效果...

无论如何,有两种解决方法:

1) 为边框赋予以下属性 RenderOptions.EdgeMode="Aliased"。这将关闭抗锯齿(0% 白色(ish)像素),但控件看起来非常参差不齐。

2) 使用两个边框。外部边框的定义就像您定义当前边框一样,只需将 Background 属性设置为 DarkBlue。然后为这个外边框创建另一个边框作为子元素。对于这个内边框,设置 CornerRadius=7,RenderOptions.EdgeMode="Aliased" 并使用 LinearGradientBrush 定义背景。内边框将包含 ContentPresenter。代码将如下所示:

<Border CornerRadius=8 Background=DarkBlue>
    <Border CornerRadius=7 RenderOptions.EdgeMode="Aliased">
       <Border.Background>
          ...
       </Border.Background>

       <ContentPresenter />
    </Border>
</Border>

它不会 100% 去除白色像素,但这是我认为的最佳折衷方案。用肉眼我看不到任何白色像素,但是当我使用放大镜工具放大时,我只计算出每个角落只有 2 个像素,而且只在底角。之前每个角大约有 8 个像素。至少外边框仍然是抗锯齿的,并且控件看起来没有锯齿状。

BevelBitmapEffect 对控件的外观没有任何影响,所以我只是省略了它。

【讨论】:

我以前在一些问题中使用过 SnapsToDevicePixels,但这里似乎不是这样。我可能会发布按钮的 Controltemplate 来向您展示它的外观。

以上是关于WPF:带有cornerRadius和Bevel的按钮模板看起来错误的主要内容,如果未能解决你的问题,请参考以下文章

仅底部带有圆角的 WPF 弹出窗口

为啥我的 CornerRadius 的 WPF 样式未在 Windows 7 中应用?

使用 CornerRadius 在边框内滚动内容

较小尺寸的按钮不是带有 layer.cornerRadius 的圆形

UILabel,带有圆角半径和阴影

c_cpp 创建一个带有圆角矩形背景的UILabel,就像在iPhone Mail应用程序中一样。 (比使用UILabel.layer.cornerRadius快得多)