views:

166

answers:

1

I changed the ControrTemplate of a button, gave it a border with CornerRadius and BevelBitmpaEffect. Looks decent enough for the minimal effort. Put it on a colored background and then the problem becomes apperent.

The corner where the lightangle is coming from there is a white snip with a right angle corner. Possibly coming from the light effect but very obvious with a cornerRadius. I don't suppose I could do anything about it ( aside from the obvious like not using a cornerRadius )?

EDIT:

This code should generate the same problem for you

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

Use this button on a LightBlue Background for example

<Border Background="LightBlue" >
    <Button Style={StaticResource TabButtons} >Test</Button>
</Border>
+2  A: 

I can't imagine what the problem exactly looks like, but here is one suggestion - try setting the SnapsToDevicePixels to true for the affected button or perhaps the entire window. The problem might stem from the fact that WPF by default wants to do device independent rendering. Which causes control edges to slightly "bleed" to adjacent pixels due to width/height and DPI/pixels not aligning exactly. Setting SnapsToDevicePixels to true, will force WPF to render exactly for the device pixels and the "bleeding" effect will dissapear...

EDIT: I tried out the code you provided and I guess the "white snip" is the white(ish) pixels around the corners? Well the problem here stems from antialiasing, which also lightens the pixels inside the corners. Because you use a dark tone, those lighter pixels stand out and the button doesn't look so nice.

I'm not sure if this can be considered a bug. You would think that antialising will do it's magic on the pixels that make up the corner and outside of the corner, but every pixel inside of the corner should be colored with the background color. Then again this might be by design, that antialiasing has to mess with the pixels inside the corner as well otherwise you don't get the required effect...

Anyway there are two workarounds:

1) Give the border the following property RenderOptions.EdgeMode="Aliased". This will turn off antialiasing (0% white(ish) pixels), but the controll will look very jaggedy.

2) Use two borders. The outer border will be defined just like you have defined your current border, only set the Background property to just DarkBlue. Then for this outer border create another border as a child element. For this inner border set CornerRadius=7, RenderOptions.EdgeMode="Aliased" and define the Background with the LinearGradientBrush. The inner border will contain the ContentPresenter. The code will look like this:

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

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

It won't get rid of the white pixels a 100%, but this is the best compromise I think. With the naked eye I couldn't see any white pixels, but when I zoomed in with the magnifier tool I counted only 2 pixels per corner and only at the bottom corners. Before it was something like 8 pixels per corner. At least the outer border is still antialiased and the control doesn't look jaggedy.

The BevelBitmapEffect didn't make any difference to the appearance of the control so I just ommited it.

Marko
I've used SnapsToDevicePixels before in some problems but here it doesn't seem to be it. I might post the Controltemplate for the button too show you how it looks like.
Ingó Vals
Check the edited answer...
Marko