1

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

Adham Ali
  • 81
  • 8
  • The DropShadowPanel is part of the open source Windows Community Toolkit. You can look at its source to see how it's implemented at https://github.com/Microsoft/WindowsCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.UI.Controls/DropShadowPanel – Rob Caplan - MSFT Aug 14 '18 at 19:50
  • I wrote a block of code depending on my understanding for the UWP DropShadowControl mechanism. And this is the block: [block](https://pastebin.com/QHHHXPn9) – Adham Ali Aug 14 '18 at 22:00
  • But it didn't get applied – Adham Ali Aug 14 '18 at 22:18
  • So is there is anything wrong in my code? – Adham Ali Aug 14 '18 at 22:18

2 Answers2

3

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);
}
Breeze Liu - MSFT
  • 3,734
  • 1
  • 10
  • 13
  • I figured this out and the shadow is applied but i overlays the element. So what is did is a special element called ShadowElement behind the MainContent. Now the shadow i applied behind the main content and this is what we want. – Adham Ali Aug 21 '18 at 19:20
  • Another issue i faced that the masks. UWP DropShadowPanel uses GetAlphaMask to get a specific kind of shadow for shapes and text. I use the same code but it doesn't work – Adham Ali Aug 21 '18 at 20:09
  • I have added the **update** part with example code, you can have a try with the GetAlphaMask method. If you delete the code that set the mask, you will see the shadow will be applied on all the canvas range. – Breeze Liu - MSFT Aug 22 '18 at 05:48
0

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