Как правильно использовать 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.
Очевидно, что это всего лишь пример фрагмента, поэтому вы можете переименовывать эти элементы с любым именем, которое пожелаете.
Надеюсь быть полезным.
;)