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

Я хочу сделать что-то, что может быть немного сложно, поскольку это новая функция в Win 10 Creators Update: я хотел бы использовать новую функцию 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?

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


person Luca Lindholm    schedule 04.04.2017    source источник


Ответы (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

person Luca Lindholm    schedule 09.04.2017
comment
Не могли бы вы добавить код, который вы использовали для решения своего вопроса? - person WJM; 11.04.2017
comment
@WJM, получилось... наслаждайся. ;) - person Luca Lindholm; 14.04.2017
comment
@LucaLindholm Можете ли вы дать ссылку на примеры в Win Dev Center? я не могу найти - person Vijay Nirmal; 29.04.2017
comment
@LucaLindholm Для достижения Акрилового Акцента не нужно столько кода. См. этот сообщение - person Vijay Nirmal; 01.05.2017
comment
Здесь следует отметить две вещи: 1) вам не нужен GaussianBlurEffect, поскольку объект HostBackdropBlur уже сам применяет эффект размытия, и 2) это не акриловый эффект, а просто эффект размытия. на содержимом экрана за окном приложения. Фактический акриловый эффект состоит из ряда эффектов, таких как размытие, оттенок, насыщенность и шум, это не просто то, что вы можете увидеть в своем коде. - person Sergio0694; 20.05.2017
comment
@ Sergio0694 Спасибо. Я уже знал, что это не полный Акриловый Акцент. На самом деле, я хотел воспроизвести даже уровень noise... есть предложения? - person Luca Lindholm; 22.05.2017
comment
Я использовал ваше решение, и оно сработало, фон всего моего приложения стал прозрачным и размытым, как и ожидалось, но произошла еще одна забавная вещь: весь мой передний план стал невидимым. это означает, что все, что я мог видеть в своем окне приложения, было прозрачным окном приложения и ничего больше, все элементы пользовательского интерфейса в моем приложении стали невидимыми на 100 процентов. Вы знаете, как я могу это исправить? - person Muhammad Touseef; 14.06.2017
comment
@touseef Дело в том, что вам не нужно применять его к вашей корневой панели, иначе все дочерние элементы исчезнут! Вам нужно создать дочерний элемент Panel, поместить его за другими дочерними элементами, а затем применить к нему Acrylic Accent. Таким образом: ‹SomePanelSubclass rootGrid›‹SomePanelSubclass AcrylicGrid/›‹AllOtherChildrenElements Canvas.ZIndex=ValueAboveZero/›‹/SomePanelSubclass›, а затем примените Acrylic Accent к AcrylicGrid (это только пример кода, очевидно... вы можете переименовать его как вам нравится, главное, чтобы вы понимали механику). ;) - person Luca Lindholm; 14.06.2017
comment
так что в основном мне нужно создать 3 контейнера для моего приложения? - person Muhammad Touseef; 15.06.2017
comment
самый внешний будет корнем макета и останется нетронутым (с прозрачным фоном). средний (дочерний элемент корня макета) будет акриловой панелью, и к ней будет применен акрил. и самый внутренний (дочерний элемент акриловой панели) должен содержать весь XAML для моего приложения, которое я хочу показать правильно? и я могу установить ZIndex в 1 только на самой внутренней панели? или мне нужно поставить ZIndex на все вложенные и дочерние элементы самой внутренней панели? - person Muhammad Touseef; 15.06.2017
comment
@touseef Нет, таким образом вы повторите ту же ошибку. Я понимаю, что немного сложно объяснить пример кода здесь, в разделе комментариев, где я не могу вложить строки, поэтому, пожалуйста, прочитайте новый ответ, который я создал в этой теме. - person Luca Lindholm; 15.06.2017

Вот пример кода XAML, чтобы избежать исчезновения других визуальных элементов, когда вы собираетесь применить акриловый акцент:

    <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". Помните: все дочерние элементы UIElement, к которым применены Acrylic Accents, «исчезнут», поэтому целевой Acrylic UIElement не должен иметь дочерних элементов.

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

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

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

;)

person Luca Lindholm    schedule 15.06.2017
comment
он работает отлично, не могли бы вы сообщить мне, есть ли способ добавить цветовой оттенок к размытию фона? Я имею в виду, да, я могу поместить еще один слой поверх него с непрозрачностью 0,5 и некоторым цветом, но тогда эффект размытия будет уменьшен, так что есть ли способ также контролировать эффект размытия и добавить оттенок? - person Muhammad Touseef; 16.06.2017
comment
К сожалению, не в Creators Update. Акриловый акцент можно будет настроить в обновлении Fall Creators Update, которое выйдет в сентябре. В сборках Insider вы уже можете экспериментировать с новыми акриловыми кистями, доступными в качестве системных ресурсов. ;) - person Luca Lindholm; 16.06.2017
comment
да, я использовал их, потому что я тоже использую инсайдерскую сборку, но минимальной целью моего приложения является юбилейное обновление, поэтому я думаю, что могу предоставить фоновую кисть для годовщины, hostbackdrop для обновления создателей и полный arylic для осеннего обновления создателей, верно? - person Muhammad Touseef; 16.06.2017
comment
Да, в самом деле. Единственный способ настроить акриловый акцент в CU на данный момент — это поместить поверх него какой-нибудь элемент с собственными свойствами фона и непрозрачности. - person Luca Lindholm; 16.06.2017