Wpf how to create inner shadow like a sunken border

266 Views Asked by At

I am trying to accomplish the inner shadow in the following image.
the sunken border result i am after
It is a sort of sunken border looking shadow. I managed to come close with linear gradient fill but it needs some blur.

<Style TargetType="{x:Type local:LargeLabelWithUnitControl}">
    <Setter Property="MaxHeight" Value="80"/>
    <Setter Property="MinHeight" Value="80"/>
    <Setter Property="MaxWidth" Value="130"/>
    <Setter Property="MinWidth" Value="130"/>
    
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:LargeLabelWithUnitControl}">
                <Border BorderThickness="6" CornerRadius="15" >
                    <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}"
                        CornerRadius="10"
                            >
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="2*"/>
                            <RowDefinition Height="*"/>
                        </Grid.RowDefinitions>
                        
                        <!-- Display the LabelText -->
                        <TextBlock Text="{Binding LabelText, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:LargeLabelWithUnitControl}}" 
                                   Foreground="{TemplateBinding Foreground}" 
                                   HorizontalAlignment="Center"
                                   FontSize="50" 
                                   FontFamily="Calibri"/>

                        <!-- Display the UnitText -->
                        <TextBlock Text="{Binding UnitText, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:LargeLabelWithUnitControl}}" 
                                   Grid.Row="1"
                                   Foreground="{TemplateBinding Foreground}" 
                                   HorizontalAlignment="Center" 
                                   FontSize="20" 
                                   FontFamily="Calibri"/>
                    </Grid>

                    
                    </Border>
                    <Border.BorderBrush>
                        <LinearGradientBrush StartPoint="0, 0" EndPoint="0.3, 0.8" >
                            <GradientStop Color="#ff095750" Offset="0.0"/>
                            <GradientStop Color="#ff148F7F" Offset="1"/>
                        </LinearGradientBrush>
                    </Border.BorderBrush>
                    
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Anyone knows how to do this?

1

There are 1 best solutions below

0
markenbargen On

So I have been on a quest to find a good answer to this very problem. So far there doesn't seem to be an easy or clean answer. This link here is good if your shape doesn't have rounded corners(or you want shading on all sides as seen in the rectangle example). https://www.codeproject.com/Articles/225076/Creating-Inner-Shadows-for-WPF-and-Silverlight

Though there doesn't seem to be a good solution for what you want. I have found something that works for my purposes, though it's not pretty in the slightest!

        <Grid>
            <Border Background="Yellow"  Width="30" Height="30"  Margin="-2"  BorderThickness="2" CornerRadius="7" >
                <!-- This blue border is hidden by the grey border -->
                <Border Background="Transparent" BorderBrush="Blue" BorderThickness="1,1,0,0" CornerRadius ="5">
                    <Border.Effect>
                        <!-- This is where the actual inneshadow is defined -->
                        <DropShadowEffect  ShadowDepth="0" BlurRadius="4" Color ="Red"/>
                    </Border.Effect>
                </Border>
            </Border>
            
            <!-- Keeps blur radius from leaking out Normally it would be the color of the background -->
            <Border  BorderBrush="Green" Margin="-3" BorderThickness="3" CornerRadius="7" />
            
             <!-- Grey border : If you want a borderless look I would recommend changing 
              this border to the background color as well or changing the size and 
               coverage of the green border -->
            <Border BorderThickness="1" CornerRadius ="5" BorderBrush="Grey" />
        </Grid>

Here is a link to the results https://i.stack.imgur.com/wTX7y.jpg, I added wacky colors so it should be clear which part is which. Again this is not a perfect solution and if anyone has anything better I would be interested. You will have to mess around with it a bit to get it to work for your purposes.

But I hope this helps someone out there!