如何在UWP合成中解决这个奇怪的DropShadow问题?

时间:2018-02-03 13:07:43

标签: c# uwp

在合成中使用投影时,我会产生不良影响。要复制此问题,请按照下列步骤操作:

第1步:创建新的UWP项目并定位 Windows 10 Fall Creators更新(10.0; Build 16299)

第2步:将以下内容复制到MainPage.xaml

<Page x:Class="App1.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      mc:Ignorable="d">
    <Grid>
        <Canvas x:Name="_shadow" Width="500" Height="500" VerticalAlignment="Top" HorizontalAlignment="Left"/>

        <Canvas x:Name="_shadowSource" Width="500" Height="500" VerticalAlignment="Top" HorizontalAlignment="Left">
            <Ellipse Width="50" Height="50" Fill="DarkOrange" Canvas.Top="50" Canvas.Left="50"/>
            <Ellipse Width="50" Height="50" Fill="Aquamarine" Canvas.Top="100" Canvas.Left="100"/>
            <Ellipse Width="50" Height="50" Fill="Crimson" Canvas.Top="150" Canvas.Left="150"/>
            <Ellipse Width="50" Height="50" Fill="BlueViolet" Canvas.Top="200" Canvas.Left="200"/>
            <Ellipse Width="50" Height="50" Fill="DarkGreen" Canvas.Top="250" Canvas.Left="250"/>
            <Ellipse Width="50" Height="50" Fill="Gold" Canvas.Top="300" Canvas.Left="300"/>
            <Ellipse Width="50" Height="50" Fill="MediumAquamarine" Canvas.Top="350" Canvas.Left="350"/>
            <Ellipse Width="50" Height="50" Fill="Violet" Canvas.Top="400" Canvas.Left="400"/>
            <Ellipse Width="50" Height="50" Fill="LightSeaGreen" Canvas.Top="450" Canvas.Left="450"/>
        </Canvas>
    </Grid>
</Page>

第3步:将以下内容复制到MainPage.xaml.cs

using System.Numerics;
using Windows.UI.Composition;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Hosting;

namespace App1
{
    public sealed partial class MainPage
    {
        public MainPage()
        {
            InitializeComponent();

            var compositor = Window.Current.Compositor;
            var shadow = compositor.CreateDropShadow();
            var layer = compositor.CreateLayerVisual();

            shadow.SourcePolicy = CompositionDropShadowSourcePolicy.InheritFromVisualContent;

            layer.Shadow = shadow;
            layer.Size = new Vector2(500, 500);

            var visual = ElementCompositionPreview.GetElementVisual(_shadowSource);

            layer.Children.InsertAtBottom(visual);

            ElementCompositionPreview.SetElementChildVisual(_shadow, layer);
        }
    }
}

_shadowSource的内容移至新图层,并将阴影设置为InheritFromVisualContent。当应用加载时,您会看到阴影渲染正常,但调整应用程序大小会产生视觉故障。

Shadow glitch

以下是注释掉//layer.Shadow = shadow;

行时会发生什么

No shadow

这里发生了什么?阴影为什么会导致这种情况?

2 个答案:

答案 0 :(得分:0)

当您的窗口高度小于500时,Either高度仍为500,因为您的XAML中有_shadowSource。因此它被剪裁,只有上半部分可见。

但是你将阴影添加到另一个名为Width="500" Height="500"的元素中。这个没有固定的大小,所以它调整到你的窗口大小,即不会发生削波。这就是为什么你的圆圈被扭曲成椭圆形,并且你在窗口的下半部分看到这些讨厌的文物 - 如果你的阴影布局正确,那么这些部分就会被剪掉并且看不见。

答案 1 :(得分:0)

我使用DropShadowPanelUWP Community Toolkit控件为椭圆应用投影。它运作良好。

您可以尝试以下方法:

<Page
    ...
    xmlns:control="using:Microsoft.Toolkit.Uwp.UI.Controls"
    ...
>    

<Canvas  VerticalAlignment="Top" HorizontalAlignment="Left">
        <control:DropShadowPanel BlurRadius="4.0" Canvas.Top="50" Canvas.Left="50"
                      ShadowOpacity="0.7"
                      OffsetX="5.0"
                      OffsetY="5.0"
                      Color="Black">
            <Ellipse Width="50" Height="50" Fill="DarkOrange" />
        </control:DropShadowPanel>
        <control:DropShadowPanel BlurRadius="4.0" Canvas.Top="100" Canvas.Left="100"
                      ShadowOpacity="0.7"
                      OffsetX="5.0"
                      OffsetY="5.0"
                      Color="Black">
            <Ellipse Width="50" Height="50" Fill="Aquamarine" />
        </control:DropShadowPanel>
        <control:DropShadowPanel BlurRadius="4.0" Canvas.Top="150" Canvas.Left="150"
                      ShadowOpacity="0.7"
                      OffsetX="5.0"
                      OffsetY="5.0"
                      Color="Black">
            <Ellipse Width="50" Height="50" Fill="Crimson" />
        </control:DropShadowPanel>
        <control:DropShadowPanel BlurRadius="4.0" Canvas.Top="200" Canvas.Left="200"
                      ShadowOpacity="0.7"
                      OffsetX="5.0"
                      OffsetY="5.0"
                      Color="Black">
            <Ellipse Width="50" Height="50" Fill="BlueViolet" />
        </control:DropShadowPanel>
        <control:DropShadowPanel BlurRadius="4.0" Canvas.Top="250" Canvas.Left="250"
                      ShadowOpacity="0.7"
                      OffsetX="5.0"
                      OffsetY="5.0"
                      Color="Black">
            <Ellipse Width="50" Height="50" Fill="DarkGreen" />
        </control:DropShadowPanel>
        <control:DropShadowPanel BlurRadius="4.0" Canvas.Top="300" Canvas.Left="300"
                      ShadowOpacity="0.7"
                      OffsetX="5.0"
                      OffsetY="5.0"
                      Color="Black">
            <Ellipse Width="50" Height="50" Fill="Gold" />
        </control:DropShadowPanel>
        <control:DropShadowPanel BlurRadius="4.0" Canvas.Top="350" Canvas.Left="350"
                      ShadowOpacity="0.7"
                      OffsetX="5.0"
                      OffsetY="5.0"
                      Color="Black">
            <Ellipse Width="50" Height="50" Fill="MediumAquamarine" />
        </control:DropShadowPanel>
        <control:DropShadowPanel BlurRadius="4.0" Canvas.Top="400" Canvas.Left="400"
                      ShadowOpacity="0.7"
                      OffsetX="5.0"
                      OffsetY="5.0"
                      Color="Black">
            <Ellipse Width="50" Height="50" Fill="Violet" />
        </control:DropShadowPanel>
        <control:DropShadowPanel BlurRadius="4.0" Canvas.Top="450" Canvas.Left="450"
                      ShadowOpacity="0.7"
                      OffsetX="5.0"
                      OffsetY="5.0"
                      Color="Black">
            <Ellipse Width="50" Height="50" Fill="LightSeaGreen" />
        </control:DropShadowPanel>
</Canvas>

我检查了它的源代码,我发现它会在调整应用程序窗口大小时更新阴影大小和其他内容。所以,也许,这是关键点。你可以 请参考其source code来扩展您自己的代码。或者您可以直接使用DropShadowPanel控件。