开发者

Wpf round weird border

Wpf round weird border

Hi

I'm trying for over 2 days now to create toggle button that in pressed state like the above image, but that upper border is giving me a headache. Does anyone have any idea how to create that round corner that goes down? The background is a linear gradient top to bottom: #b8c7d6 - #a8b3c4

Any help at all would be greatly appreciated!!

I have something like this but it is far from the design:

<Style x:Key="ToggleButtonStyle" TargetType="{x:Type ToggleButton}">
    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
    <Setter Property="HorizontalContentAlignment" Value="Center"/>
    <Setter Property="VerticalContentAlignment" Value="Center"/>
    <Setter Property="Padding" Value="1"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ToggleButton}">
                <Grid>
                    <Border Background="Black" BorderThickness="1" BorderBrush="#FF4E4F50" CornerRadius="3"/>
                    <Border Background="Black" Margin="1" CornerRadius="3"/>
                    <Border Margin="2" CornerRadius="3">
                        <Border.Background>
                            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                <GradientStop Color="#0099B9D1" Offset="0"/>
                                <GradientStop Color="#FF99B9D1" Offset="1"/>
                                <GradientStop Color="#B299B9D1" Offset="0.054"/>
                            </LinearGradientBrush>
                        </Border.Background>
                    </Border>
                    <Border Margin="2" CornerRadius="3" Opacity="0.3">
                        <Border.Background>
                            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                <LinearGradientBrush.RelativeTransform>
                                    <TransformGroup>
                                        <ScaleTransform CenterY="0.5" CenterX="0.5"/>
                                        <SkewTransform CenterY="0.5" CenterX="0.5"/>
                                        <RotateTransform Angle="90" CenterY="0.5" CenterX="0.5"/>
                                        <TranslateTransform/>
                                    </TransformGroup>
                                </LinearGradientBrush.RelativeTransform>
                                <GradientStop Color="Black" Offset="0"/>
                                <GradientStop Color="Black" Offset="1"/>
                                <GradientStop Color="#00090909" Offset="0.022"/>
                                <GradientStop Color="#00000000" Offset="0.99"/>
                                <GradientStop Color="#45060606" Offset="0.001"/>
                            </LinearGradientBrush>
                        </Border.Background></Borde开发者_C百科r>

                    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                    </Grid>


                <ControlTemplate.Triggers>
                    <Trigger Property="IsKeyboardFocused" Value="true">

                    </Trigger>
                    <Trigger Property="IsChecked" Value="true">

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


Here's what worked well for me. I found that the rounded corners added some additional challenges with creating the top area shadow correctly, but I was able to get that working by combining several techniques.

The first technique involves the clever use of two Borders. The outer border has its ClipToBounds set to true, and the inner Border has a DropShadowEffect, with ShadowDepth set to 0 and a BlurRadius of around 5. This gets us part of what we need, but it won't handle the rounded corner issue (we'll get to that). This technique can be found at this article. Here's the gist of it:

<Border BorderBrush="DarkGray" BorderThickness="1" ClipToBounds="True">
  <Border BorderBrush="Black" BorderThickness="1" Margin="-1">
    <Border.Effect>
      <DropShadowEffect ShadowDepth="0" BlurRadius="6">
    </Border.Effect>
  </Border>
</Border>

If I recall correctly, at this point we would have something close to what you want, except that the DropShadowEffect "bleeds" out of the rounded corners (again we'll address that soon).

Another problem we would now have is that any child elements that we place inside the inner Border would also have the DropShadowEffect applied to them! To correct that problem, we need the second technique. Place the two Borders, along with another container (to hold your content) into a Grid, so that the outer Border and the new container are siblings. This will cause the siblings to overlap each other, while only applying the DropShadowEffect to the Border. See this answer.

Now to address the "bleed" issue, where the DropShadowEffect does not follow the contour of the rounded corners, but rather acts as if the corners were straight. This requires the third technique. We need to use Michah's ClippingBorder custom control. We need to replace the above-mentioned outer Border control with his ClippingBorder, still keeping ClipToBounds set to true. This will trim off the bleed at the rounded corners.

I was able to combine these three techniques to create a "sunk in" (or "inset") border look. It looked something like:

<Grid>      
    <local:ClippingBorder x:Name="TopShadowClippingBorder" 
        BorderThickness="0" 
        CornerRadius="5" 
        ClipToBounds="True">

        <Border x:Name="TopShadowBorder" 
                BorderBrush="#D8333333" BorderThickness=".5,1,.5,0" 
                Padding="0" 
                CornerRadius="5" 
                ClipToBounds="True">        
                <Border.Effect>
                       <DropShadowEffect Direction="270" ShadowDepth="0.5"/>
                </Border.Effect>
        </Border>
    </local:ClippingBorder>

    <Border x:Name="InsetBorder" 
            BorderBrush="#99A1A1A1" BorderThickness="0.5,0,0.5,1" 
            CornerRadius="5" />

    <StackPanel x:Name="Contents_StackPanel" Orientation="Horizontal" Margin="5,5,5,5">
        (Contents go here...)
    </StackPanel>
</Grid>

Wpf round weird border

Notice that the upper "glow" (DropShadowEffect) nicely follows the contour of the rounded corner of the Border:

Wpf round weird border


I would use two borders: the outer would look something like:

<Border CornerRadius="3" BorderBrush="White" BorderThickness="1">

The inner would create the shadow effect as follows:

<Border CornerRadius="3" BorderThickness="2,4,2,0">
    <Border.BorderBrush>
        <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
            <GradientStop Offset="0" Color="Black"/>
            <GradientStop Offset="0.2" Color="#00000000"/>
        </LinearGradientBrush>
    </Border.BorderBrush>

Obviously you'll need to tweak the values, but that should at least produce the effect you're after.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜