Как правильно использовать Acrylic Accent (CreateHostBackDropBrush()) в Windows 10 Creators Update?

Я хочу сделать что-то, что может быть немного сложнее, так как это новая функция в обновлении Win 10 Creators: я хотел бы использовать новую функцию Acrylic Accent для создания прозрачных окон в приложениях UWP. Я видел, что Microsoft уже представляет его в Groove и Film & TV в 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, как Page или Panel?

Я очень признателен за вашу помощь, спасибо.

2 ответа

Решение

Решил сам: пришлось уточнять SpriteVisual размер вручную (чтобы он соответствовал UIElement цель) и sizeChanged событие самого UIElement.

Вот пример кода, я использовал общий 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

Вот пример кода 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>

Вы должны наносить Акриловый Акцент ТОЛЬКО на "AcrylicGrid". Помните: все дочерние элементы UIElement, к которым применены акриловые акценты, будут "исчезать", поэтому целевой акриловый UIElement не должен иметь дочерних элементов.

Вы можете поместить все остальные элементы XAML в один элемент IPanel, чтобы упростить использование Canvas.ZIndex, чтобы применить его только к самой Panel.

Очевидно, что это всего лишь пример фрагмента, поэтому вы можете переименовывать эти элементы с любым именем, которое пожелаете.

Надеюсь быть полезным.

;)

Другие вопросы по тегам