Search code examples
c#uwpcompositionwin2d

Drop Shadow effect on Windows SDK 10240


I know there are a lot of ways of adding shadows with the Anniversary Update and previous SDKs with Windows.Composition. Unfortunately I have to stick with version 10240 and this APIs are not available. I tried with Win2D but did not succeed. Any ideas on how to add a shadow to a Grid XAML element?


Solution

  • To my knowledge you can't make a real drop shadow without the anniversary update in xaml (without using specific shadow bitmaps that you'd need to create yourself).

    In case you only need a shadow to rectangular xaml components, you can make a 3x3 grid with gradients along the edges, and place it under the component with a certain offset (depending on where you want the light to come from).

    Here is an example of that:

    <UserControl
    x:Class="YourProject.UserControls.CustomShadow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:YourProject.UserControls"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300"
    d:DesignWidth="400">
    
    <Grid>
        <Grid x:Name="ShadowGrid" Opacity="0.2">
            <Grid.ColumnDefinitions>
                <ColumnDefinition x:Name="LeftColumn" Width="40"/>
                <ColumnDefinition x:Name="CenterColumn" />
                <ColumnDefinition x:Name="RightColumn" Width="40" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition x:Name="TopRow" Height="40"/>
                <RowDefinition x:Name="CenterRow" />
                <RowDefinition x:Name="BottomRow" Height="40"/>
            </Grid.RowDefinitions>
    
            <Grid Grid.Row="0" Grid.Column="0">
                <Rectangle>
                    <Rectangle.Fill>
                        <LinearGradientBrush StartPoint="0.5,0.5" EndPoint="1,1">
                            <GradientStop Color="#4b4b50" Offset="1" />
                            <GradientStop Color="Transparent" Offset="0"/>
                        </LinearGradientBrush>
                    </Rectangle.Fill>
                </Rectangle>
            </Grid>
            <Grid Grid.Row="0" Grid.Column="1">
                <Rectangle>
                    <Rectangle.Fill>
                        <LinearGradientBrush StartPoint="0,1" EndPoint="0,0">
                            <GradientStop Color="#4b4b50" Offset="0" />
                            <GradientStop Color="Transparent" Offset="1"/>
                        </LinearGradientBrush>
                    </Rectangle.Fill>
                </Rectangle>
            </Grid>
            <Grid Grid.Row="0" Grid.Column="2">
                <Rectangle>
                    <Rectangle.Fill>
                        <LinearGradientBrush StartPoint="0.5,0.5" EndPoint="0,1">
                            <GradientStop Color="#4b4b50" Offset="1" />
                            <GradientStop Color="Transparent" Offset="0"/>
                        </LinearGradientBrush>
                    </Rectangle.Fill>
                </Rectangle>
            </Grid>
            <Grid Grid.Row="1" Grid.Column="0">
                <Rectangle>
                    <Rectangle.Fill>
                        <LinearGradientBrush StartPoint="1,0" EndPoint="0,0">
                            <GradientStop Color="#4b4b50" Offset="0" />
                            <GradientStop Color="Transparent" Offset="1"/>
                        </LinearGradientBrush>
                    </Rectangle.Fill>
                </Rectangle>
            </Grid>
            <Grid Grid.Row="1" Grid.Column="1">
                <Rectangle Fill="#4b4b50"/>
            </Grid>
            <Grid Grid.Row="1" Grid.Column="2">
                <Rectangle>
                    <Rectangle.Fill>
                        <LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
                            <GradientStop Color="#4b4b50" Offset="0" />
                            <GradientStop Color="Transparent" Offset="1"/>
                        </LinearGradientBrush>
                    </Rectangle.Fill>
                </Rectangle>
            </Grid>
            <Grid Grid.Row="2" Grid.Column="0">
                <Rectangle>
                    <Rectangle.Fill>
                        <LinearGradientBrush StartPoint="0.5,0.5" EndPoint="1,0">
                            <GradientStop Color="#4b4b50" Offset="1" />
                            <GradientStop Color="Transparent" Offset="0"/>
                        </LinearGradientBrush>
                    </Rectangle.Fill>
                </Rectangle>
            </Grid>
            <Grid Grid.Row="2" Grid.Column="1">
                <Rectangle>
                    <Rectangle.Fill>
                        <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                            <GradientStop Color="#4b4b50" Offset="0" />
                            <GradientStop Color="Transparent" Offset="1"/>
                        </LinearGradientBrush>
                    </Rectangle.Fill>
                </Rectangle>
            </Grid>
            <Grid Grid.Row="2" Grid.Column="2">
                <Rectangle>
                    <Rectangle.Fill>
                        <LinearGradientBrush StartPoint="0.5,0.5" EndPoint="0,0">
                            <GradientStop Color="#4b4b50" Offset="1" />
                            <GradientStop Color="Transparent" Offset="0"/>
                        </LinearGradientBrush>
                    </Rectangle.Fill>
                </Rectangle>
            </Grid>
        </Grid>
        <Grid>
            <Rectangle Fill="Transparent" Width="350" Height="250" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10"/>
        </Grid>
    </Grid>
    

    When resizing the object, adjust the width/height of CenterColumn/CenterRow, and keep the other parts of the grid the same size. A radial gradient would've looked better in the corners, but radial gradients don't exist in uwp either.