Используйте материалы Mica или Акрил в настольных приложениях для Windows 11
Материалы в Windows 11 — это визуальные эффекты, применяемые к поверхностям пользовательского интерфейса, которые похожи на артефакты реальной жизни. Материалы, обладающие遮光ными свойствами, такие как слюда и акрил, используются в качестве базовых слоев под интерактивными элементами управления пользовательским интерфейсом.
Мика является непрозрачным материалом, который включает тему пользователя и обои на рабочем столе, чтобы создать высокоперсонализированный внешний вид. Мика предназначена для повышения производительности, так как она фиксирует фоновые обои только один раз, чтобы создать её визуализацию, поэтому мы рекомендуем её для базового слоя вашего приложения, особенно в области строки заголовка.
Акрил — полупрозрачный материал, который реплицирует эффект заморозки стекла. Он используется только для временных поверхностей, закрывающих свет, таких как всплывающие элементы и контекстные меню.
В этой статье описывается, как применить Мику или Акрил в качестве базового слоя приложения Windows App SDK/WinUI 3 XAML.
Примечание.
- Чтобы использовать AcrylicBrush в приложении, см. Acrylic material.
- Чтобы использовать материалы фона в приложении Win32, см. статью Apply Mica in Win32 desktop apps for Windows 11.
- Чтобы использовать фоновые материалы в приложении UWP/WinUI 2, см. статью Apply Mica with WinUI 2 for UWP или Акриловый материал.
Использование фонового материала
Приложение WinUI 3 Gallery включает интерактивные примеры большинства элементов управления, функций и возможностей WinUI 3. Получение приложения из Microsoft Store или получение исходного кода на GitHub
Чтобы применить к вашему приложению материал Mica или Акрил, вы назначаете свойство
Эти элементы имеют SystemBackdrop
свойство:
- CommandBarFlyoutCommandBar.SystemBackdrop
- ContentIsland.SystemBackdrop
- DesktopWindowXamlSource.SystemBackdrop
- FlyoutBase.SystemBackdrop
- MenuFlyoutPresenter.SystemBackdrop
- Popup.SystemBackdrop
- Window.SystemBackdrop
В этих примерах показано, как задать системный фон в XAML и коде.
Mica
Мика обычно используется в качестве фона для окна приложения.
<Window
... >
<Window.SystemBackdrop>
<MicaBackdrop Kind="BaseAlt"/>
</Window.SystemBackdrop>
</Window>
public MainWindow()
{
this.InitializeComponent();
SystemBackdrop = new MicaBackdrop()
{ Kind = MicaKind.BaseAlt };
}
Акрил
Акрил обычно используется в качестве фона для временного пользовательского интерфейса, например всплывающего меню.
<Flyout
... >
<Flyout.SystemBackdrop>
<DesktopAcrylicBackdrop/>
</Flyout.SystemBackdrop>
</Flyout>
Flyout flyout = new Flyout()
{
SystemBackdrop = new DesktopAcrylicBackdrop()
};
Использование системного контроллера фона
Примечание.
Начиная с версии 1.3 Windows App SDK, вы можете применить материал, установив свойство Window.SystemBackdrop
для элемента XAML SystemBackdrop
, как описано в предыдущем разделе. Это рекомендуемый способ применения материала.
Оставшаяся часть этой статьи показывает, как использовать API Composition MicaController и DesktopAcrylicController.
Чтобы использовать фоновый материал в приложении, можно использовать один из контроллеров, реализующих интерфейс ISystemBackdropController (MicaController или DesktopAcrylicController). Эти классы управляют как отображением материалов заднего фона системы, так и управлением системной политикой, связанной с этими материалами.
Чтобы использовать Mica в качестве фонового материала, создайте объект MicaController . Чтобы использовать Акрил, создайте объект DesktopAcrylicController . Настройка и поддерживающий код одинаковы для всех типов материалов фона системы.
В этом коде показано, как создать MicaController
.
MicaController m_backdropController;
bool TrySetSystemBackdrop()
{
if (MicaController.IsSupported())
{
...
m_backdropController = new MicaController();
...
}
}
// namespace MUCSB = Microsoft::UI::Composition::SystemBackdrops;
winrt::MUCSB::MicaController m_backdropController{ nullptr };
void SetBackground()
{
if (winrt::MUCSB::MicaController::IsSupported())
{
...
m_backdropController = winrt::MUCSB::MicaController();
...
}
}
Чтобы использовать вариант Mica Alt, создайте MicaController
объект и установите для свойства Kind значение MicaKind.BaseAlt.
MicaController m_backdropController;
bool TrySetSystemBackdrop()
{
if (MicaController.IsSupported())
{
...
m_backdropController = new MicaController()
{
Kind = MicaKind.BaseAlt
};
...
}
}
// namespace MUCSB = Microsoft::UI::Composition::SystemBackdrops;
winrt::MUCSB::MicaController m_backdropController{ nullptr };
void SetBackground()
{
if (winrt::MUCSB::MicaController::IsSupported())
{
...
m_backdropController = winrt::MUCSB::MicaController();
m_backdropController.Kind(winrt::MUCSB::MicaKind::BaseAlt);
...
}
}
В этом коде показано, как создать DesktopAcrylicController
объект.
DesktopAcrylicController m_backdropController;
bool TrySetSystemBackdrop()
{
if (DesktopAcrylicController.IsSupported())
{
...
m_backdropController = new DesktopAcrylicController();
...
}
}
// namespace MUCSB = Microsoft::UI::Composition::SystemBackdrops;
winrt::MUCSB::DesktopAcrylicController m_backdropController{ nullptr };
void SetBackground()
{
if (winrt::MUCSB::DesktopAcrylicController::IsSupported())
{
...
m_backdropController = winrt::MUCSB::DesktopAcrylicController();
...
}
}
Контроллер реагирует на системные темы Light и Dark по умолчанию. Чтобы переопределить это поведение, можно задать следующие свойства на контроллере:
Примечание.
После настройки любого из четырех свойств контроллера он больше не применяет значения по умолчанию Light или Dark при изменении связанного SystemBackdropConfiguration.Theme. Необходимо вручную обновить эти свойства, чтобы соответствовать новой теме.
Чтобы использовать фоновый материал в приложении, требуются следующие элементы:
Поддержка системы
Система, в которой выполняется приложение, должна поддерживать материал фона. Вызовите метод MicaController.IsSupported или DesktopAcrylicController.IsSupported, чтобы обеспечить поддержку фонового материала во время выполнения.
Допустимый целевой объект
Необходимо предоставить целевой объект, реализующий интерфейс ICompositionSupportsSystemBackdrop . В XAML-приложении элемент Window реализует этот интерфейс и используется в качестве цели заднего плана.
Объект SystemBackdropConfiguration
SystemBackdropConfiguration предоставляет контроллер фона системы с информацией о политике для конкретного приложения, чтобы правильно настроить материал фона системы.
DispatcherQueue объект.
Вам нужно, чтобы на основном потоке XAML была доступна Windows.System.DispatcherQueue. См.
WindowsSystemDispatcherQueueHelper
класс в примере кода или в примере коллекции WinUI 3.
Пример. Использование Mica в приложении Windows AppSDK/WinUI 3
В этом примере показано, как настроить материал фона Mica в приложении XAML.
Совет
Кроме того, см. следующие примеры проектов на сайте GitHub:
C#: SampleSystemBackdropsWindow в галерее WinUI3.
C++/WinRT: пример Mica для Windows App SDK.
using Microsoft.UI.Composition.SystemBackdrops;
using Microsoft.UI.Xaml;
using System.Runtime.InteropServices; // For DllImport
using WinRT; // required to support Window.As<ICompositionSupportsSystemBackdrop>()
public sealed partial class MainWindow : Window
{
WindowsSystemDispatcherQueueHelper m_wsdqHelper; // See below for implementation.
MicaController m_backdropController;
SystemBackdropConfiguration m_configurationSource;
public MainWindow()
{
this.InitializeComponent();
TrySetSystemBackdrop();
}
bool TrySetSystemBackdrop()
{
if (Microsoft.UI.Composition.SystemBackdrops.MicaController.IsSupported())
{
m_wsdqHelper = new WindowsSystemDispatcherQueueHelper();
m_wsdqHelper.EnsureWindowsSystemDispatcherQueueController();
// Create the policy object.
m_configurationSource = new SystemBackdropConfiguration();
this.Activated += Window_Activated;
this.Closed += Window_Closed;
((FrameworkElement)this.Content).ActualThemeChanged += Window_ThemeChanged;
// Initial configuration state.
m_configurationSource.IsInputActive = true;
SetConfigurationSourceTheme();
m_backdropController = new Microsoft.UI.Composition.SystemBackdrops.MicaController();
// Enable the system backdrop.
// Note: Be sure to have "using WinRT;" to support the Window.As<...>() call.
m_backdropController.AddSystemBackdropTarget(this.As<Microsoft.UI.Composition.ICompositionSupportsSystemBackdrop>());
m_backdropController.SetSystemBackdropConfiguration(m_configurationSource);
return true; // succeeded
}
return false; // Mica is not supported on this system
}
private void Window_Activated(object sender, WindowActivatedEventArgs args)
{
m_configurationSource.IsInputActive = args.WindowActivationState != WindowActivationState.Deactivated;
}
private void Window_Closed(object sender, WindowEventArgs args)
{
// Make sure any Mica/Acrylic controller is disposed
// so it doesn't try to use this closed window.
if (m_backdropController != null)
{
m_backdropController.Dispose();
m_backdropController = null;
}
this.Activated -= Window_Activated;
m_configurationSource = null;
}
private void Window_ThemeChanged(FrameworkElement sender, object args)
{
if (m_configurationSource != null)
{
SetConfigurationSourceTheme();
}
}
private void SetConfigurationSourceTheme()
{
switch (((FrameworkElement)this.Content).ActualTheme)
{
case ElementTheme.Dark: m_configurationSource.Theme = Microsoft.UI.Composition.SystemBackdrops.SystemBackdropTheme.Dark; break;
case ElementTheme.Light: m_configurationSource.Theme = Microsoft.UI.Composition.SystemBackdrops.SystemBackdropTheme.Light; break;
case ElementTheme.Default: m_configurationSource.Theme = Microsoft.UI.Composition.SystemBackdrops.SystemBackdropTheme.Default; break;
}
}
}
class WindowsSystemDispatcherQueueHelper
{
[StructLayout(LayoutKind.Sequential)]
struct DispatcherQueueOptions
{
internal int dwSize;
internal int threadType;
internal int apartmentType;
}
[DllImport("CoreMessaging.dll")]
private static extern int CreateDispatcherQueueController([In] DispatcherQueueOptions options, [In, Out, MarshalAs(UnmanagedType.IUnknown)] ref object dispatcherQueueController);
object m_dispatcherQueueController = null;
public void EnsureWindowsSystemDispatcherQueueController()
{
if (Windows.System.DispatcherQueue.GetForCurrentThread() != null)
{
// one already exists, so we'll just use it.
return;
}
if (m_dispatcherQueueController == null)
{
DispatcherQueueOptions options;
options.dwSize = Marshal.SizeOf(typeof(DispatcherQueueOptions));
options.threadType = 2; // DQTYPE_THREAD_CURRENT
options.apartmentType = 2; // DQTAT_COM_STA
CreateDispatcherQueueController(options, ref m_dispatcherQueueController);
}
}
}
// pch.h
...
#include <winrt/Microsoft.UI.Composition.SystemBackdrops.h>
#include <winrt/Windows.System.h>
#include <dispatcherqueue.h>
// MainWindow.xaml.h
...
namespace winrt
{
namespace MUC = Microsoft::UI::Composition;
namespace MUCSB = Microsoft::UI::Composition::SystemBackdrops;
namespace MUX = Microsoft::UI::Xaml;
namespace WS = Windows::System;
}
...
struct MainWindow : MainWindowT<MainWindow>
{
winrt::MUCSB::SystemBackdropConfiguration m_configuration{ nullptr };
winrt::MUCSB::MicaController m_backdropController{ nullptr };
winrt::MUX::Window::Activated_revoker m_activatedRevoker;
winrt::MUX::Window::Closed_revoker m_closedRevoker;
winrt::MUX::FrameworkElement::ActualThemeChanged_revoker m_themeChangedRevoker;
winrt::MUX::FrameworkElement m_rootElement{ nullptr };
winrt::WS::DispatcherQueueController m_dispatcherQueueController{ nullptr };
MainWindow::MainWindow()
{
InitializeComponent();
SetBackground();
m_closedRevoker = this->Closed(winrt::auto_revoke, [&](auto&&, auto&&)
{
if (nullptr != m_backdropController)
{
m_backdropController.Close();
m_backdropController = nullptr;
}
if (nullptr != m_dispatcherQueueController)
{
m_dispatcherQueueController.ShutdownQueueAsync();
m_dispatcherQueueController = nullptr;
}
});
}
void SetBackground()
{
if (winrt::MUCSB::MicaController::IsSupported())
{
// We ensure that there is a Windows.System.DispatcherQueue on the current thread.
// Always check if one already exists before attempting to create a new one.
if (nullptr == winrt::WS::DispatcherQueue::GetForCurrentThread() &&
nullptr == m_dispatcherQueueController)
{
m_dispatcherQueueController = CreateSystemDispatcherQueueController();
}
// Setup the SystemBackdropConfiguration object.
SetupSystemBackdropConfiguration();
// Setup Mica on the current Window.
m_backdropController = winrt::MUCSB::MicaController();
m_backdropController.SetSystemBackdropConfiguration(m_configuration);
m_backdropController.AddSystemBackdropTarget(
this->m_inner.as<winrt::MUC::ICompositionSupportsSystemBackdrop>());
}
else
{
// The backdrop material is not supported.
}
}
winrt::WS::DispatcherQueueController CreateSystemDispatcherQueueController()
{
DispatcherQueueOptions options
{
sizeof(DispatcherQueueOptions),
DQTYPE_THREAD_CURRENT,
DQTAT_COM_NONE
};
::ABI::Windows::System::IDispatcherQueueController* ptr{ nullptr };
winrt::check_hresult(CreateDispatcherQueueController(options, &ptr));
return { ptr, take_ownership_from_abi };
}
void SetupSystemBackdropConfiguration()
{
m_configuration = winrt::MUCSB::SystemBackdropConfiguration();
// Activation state.
m_activatedRevoker = this->Activated(winrt::auto_revoke,
[&](auto&&, MUX::WindowActivatedEventArgs const& args)
{
m_configuration.IsInputActive(
winrt::MUX::WindowActivationState::Deactivated != args.WindowActivationState());
});
// Initial state.
m_configuration.IsInputActive(true);
// Application theme.
m_rootElement = this->Content().try_as<winrt::MUX::FrameworkElement>();
if (nullptr != m_rootElement)
{
m_themeChangedRevoker = m_rootElement.ActualThemeChanged(winrt::auto_revoke,
[&](auto&&, auto&&)
{
m_configuration.Theme(
ConvertToSystemBackdropTheme(m_rootElement.ActualTheme()));
});
// Initial state.
m_configuration.Theme(
ConvertToSystemBackdropTheme(m_rootElement.ActualTheme()));
}
}
winrt::MUCSB::SystemBackdropTheme ConvertToSystemBackdropTheme(
winrt::MUX::ElementTheme const& theme)
{
switch (theme)
{
case winrt::MUX::ElementTheme::Dark:
return winrt::MUCSB::SystemBackdropTheme::Dark;
case winrt::MUX::ElementTheme::Light:
return winrt::MUCSB::SystemBackdropTheme::Light;
default:
return winrt::MUCSB::SystemBackdropTheme::Default;
}
}
...
};
...
Связанные статьи
Windows developer