如何在Windows 10 Creators Update中正确使用Acrylic Accent(CreateHostBackDropBrush())?

时间:2017-04-04 13:36:01

标签: c# uwp windows-composition-api

我想做一些可能有点棘手的事情,因为它是Win 10 Creators Update中的新功能:我想使用新的Acrylic Accent功能在UWP应用程序中制作透明的Windows。 我看到微软已经在Groove和Film& amp; Fast Insider Ring中的电视。

这是我开发的代码,使用Win Dev Center中的示例以及Stack Overflow上的其他一些答案:

public sealed partial class MainPage : Page
{
    // Some other things

    private void initializeInterface()
    {

        /// Applying Acrylic Accent
        LayoutRoot.Background = null;

        GaussianBlurEffect blurEffect = new GaussianBlurEffect()
        {
            Name = "Blur",
            BlurAmount = 5.0f,
            BorderMode = EffectBorderMode.Hard,
            Optimization = EffectOptimization.Balanced,
            Source = new CompositionEffectSourceParameter("source"),
        };

        LayoutRoot.Background = null;

        var rootVisual = ElementCompositionPreview.GetElementVisual(LayoutRoot as UIElement);
        var compositor = rootVisual.Compositor;
        var factory = compositor.CreateEffectFactory(blurEffect);
        var effectBrush = factory.CreateBrush();

        // This is the effect I wanted to use, the "Acrylic Accent", as it is called by MS itself.
        var backdropBrush = compositor.CreateHostBackdropBrush();             
        effectBrush.SetSourceParameter("source", backdropBrush);

        var blurVisual = compositor.CreateSpriteVisual();
        blurVisual.Brush = effectBrush;
        ElementCompositionPreview.SetElementChildVisual(LayoutRoot as UIElement, blurVisual); 
    }
}

其中LayoutRoot是用作根面板的RelativePanel

但有些事情不起作用:什么? 如何将其应用于UIElement,例如PagePanel

非常感谢你的帮助,谢谢。

2 个答案:

答案 0 :(得分:2)

由我自己解决:必须手动指定SpriteVisual大小(使其适合UIElement目标)和UIElement本身的sizeChanged事件。

以下是示例代码,我使用了通用Panel类(为了轻松使用Panel.ActualWidth/ActualHeight属性...),但每个UIElement都适用于丙烯酸效果:

    private Compositor compositor;
    private SpriteVisual hostVisual;

    private void applyAcrylicAccent(Panel e)
        {
            compositor = ElementCompositionPreview.GetElementVisual(e).Compositor;
            hostVisual = compositor.CreateSpriteVisual();
            hostVisual.Size = new System.Numerics.Vector2((float)e.ActualWidth, (float)e.ActualHeight);

        // You can choose which effect you want, it is indifferent 
        GaussianBlurEffect blurEffect = new GaussianBlurEffect()
        {
            Name = "Blur",
            BlurAmount = 0.0f,
            BorderMode = EffectBorderMode.Hard,
            Optimization = EffectOptimization.Balanced,
            Source = new CompositionEffectSourceParameter("source"),
        };

        var factory = compositor.CreateEffectFactory(blurEffect, null);
        var effectBrush = factory.CreateBrush();

        effectBrush.SetSourceParameter("source", compositor.CreateHostBackdropBrush());

        hostVisual.Brush = effectBrush;
        ElementCompositionPreview.SetElementChildVisual(e, hostVisual);
    }

以及与目标sizeChanged相关联的UIElement事件(此处称为LayoutRoot):

private void LayoutRoot_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        if (hostVisual != null)
        {
            hostVisual.Size = new System.Numerics.Vector2((float)e.NewSize.Width, (float)e.NewSize.Height);
        }
    }

享受。

d

答案 1 :(得分:1)

以下是示例XAML代码,以避免在您要应用Acrylic Accent时其他视觉元素消失:

    <SomePanelSubclass "rootGrid">
       <SomePanelSubclassForAcrylic>
           <SomePanelSubclass "AcrylicGrid"/>
           <!-- Comment: some background is needed in order to make elements more visible -->
           <SomeElementWithBackgroundProperty Background="SomeBrush" Canvas.ZIndex="ValueAboveZero"/>
       </SomePanelSubclassForAcrylic>
       <AllOtherChildrenElements Canvas.ZIndex="ValueAboveZero"/>
    </SomePanelSubclass>

您应仅将Acrylic Accent应用于“AcrylicGrid”。 请记住:应用了Acrylic Accents的UIElement的所有子元素都将“消失”,因此目标Acrylic UIElement不能有子项。

您可以将所有其他XAML元素放入单个IPanel元素中,以简化Canvas.ZIndex事物,以便仅将其应用于Panel本身。

显然,这只是一个示例代码段,因此您可以使用您想要的每个名称重命名这些元素。

希望能提供帮助。