UWP. How To Implement drop shadow in code without using DropShadowPanel in

2.3k views Asked by At

I'm not an expert in using Windows composition APIs. How to implement a DropShadow on either a control or a layout or any visual control in UWP without using a DropShadowPanel for some purposes. An attached example would be awesome. Also please make sure that the shadow effect is behind the control and doesn't overlay it

2

There are 2 answers

3
Breeze Liu - MSFT On

In your code, you have created a SpriteVisual from the control's Compositor and configure the SpriteVisual's shadow, but you don't set this SpriteVisual named shadowVisual as a child of the Visual tree so that you can not see the shadow to be applied. You can just put the following code in your code block's end.

...
ElementCompositionPreview.SetElementChildVisual(Control, shadowVisual);

Your code will look like this:

//Control is the control the shadow is applied to. e.g. Button, TextBlock etc.
Compositor compositor = ElementCompositionPreview.GetElementVisual(Control).Compositor;
var shadowVisual = compositor.CreateSpriteVisual();
var dropShadow = compositor.CreateDropShadow();
shadowVisual.Shadow = dropShadow;

//UpdateShadowSize
Vector2 newSize = new Vector2(0, 0);
if (Control is FrameworkElement contentFE)
{
    newSize = new Vector2((float)contentFE.ActualWidth, (float)contentFE.ActualHeight);
    //newSize = new Vector2(200, 60);
}
shadowVisual.Size = newSize;

//Some hardcoded values for now
dropShadow.BlurRadius = 8;
dropShadow.Opacity = 0.3f;
dropShadow.Offset = new Vector3(new Vector2(2, 2), 0);
dropShadow.Color = Windows.UI.Colors.Black;

// Sets a Visual as child of the Control’s visual tree.
ElementCompositionPreview.SetElementChildVisual(Control, shadowVisual);

Note: I changed the dropShadow.Opacity to be 0.3f to make the shadow more clear.

---Update---

Yeah, you can put a special element behind the MainContent then create the shadow from this element to make the shadow behind the Main content. GetAlphaMask method should work, here is an example, you can have a try.

xaml:

<Grid Loaded="Grid_Loaded">
    <!-- Canvas to create shadow-->
    <Canvas Name="canvas"/>
    <TextBlock x:Name="textBlcok" Text="this is text blcok for test shadow"/>
</Grid>

Code behind:

private void Grid_Loaded(object sender, RoutedEventArgs e)
{
    //The canvas is the element to create shadow
    var compositor = ElementCompositionPreview.GetElementVisual(canvas).Compositor;
    var dropShadow = compositor.CreateDropShadow();
    dropShadow.Color = Colors.Green;
    dropShadow.BlurRadius = 8;
    dropShadow.Opacity = 20.0f;
    dropShadow.Offset = new Vector3(2.5F, 2.5F, 0);

    //The textBlock is the main content
    var mask = textBlcok.GetAlphaMask();
    dropShadow.Mask = mask;

    var spriteVisual = compositor.CreateSpriteVisual();
    spriteVisual.Size = new Vector2((float)canvas.ActualWidth, (float)canvas.ActualHeight);

    spriteVisual.Shadow = dropShadow;

    ElementCompositionPreview.SetElementChildVisual(canvas, spriteVisual);
}
0
Abdulghani Albaik On

https://www.microsoft.com/en-us/p/windows-community-toolkit-sample-app/9nblggh4tlcq

This app contains many of controls to build a beautiful uwp applications, it has a shadow library you can see how to implement it in your project and give you a shadow to any control