Aracılığıyla paylaş


Windows 11 için masaüstü uygulamalarında Mica veya Akrilik malzemeleri uygulama

Windows 11 'daki Malzemeleri, gerçek hayattaki yapıtlara benzeyen UX yüzeylerine uygulanan görsel efektlerdir. Mica ve Akrilik gibi tıkanıklık malzemeleri, etkileşimli kullanıcı arabirimi denetimlerinin altında temel katmanlar olarak kullanılır.

Mica, son derece kişiselleştirilmiş bir görünüm oluşturmak için kullanıcının temasını ve masaüstü duvar kağıdını içeren opak bir malzemedir. Mica, görselleştirmesini oluşturmak için arka plan duvar kağıdını yalnızca bir kez yakaladığından performans için tasarlanmıştır, bu nedenle özellikle başlık çubuğu alanında uygulamanızın temel katmanı için bunu öneririz.

Akrilik, buzlu camın etkisini çoğaltan yarı saydam bir malzemedir. Yalnızca açılır menüler ve bağlam menüleri gibi geçici, hızlı kapatılabilen yüzeyler için kullanılır.

Bu makalede, Windows Uygulama SDK'nızın/WinUI 3 XAML uygulamanızın temel katmanı olarak Mica veya Akrilik'in nasıl uygulanacağı açıklanmaktadır.

Not

Arka plan malzemesi nasıl kullanılır?

WinUI 3 Galerisi uygulaması çoğu WinUI 3 denetimine, özelliğine ve işlevselliğine ilişkin etkileşimli örnekler içerir. Uygulamayı Microsoft Store edinin veya kaynak kodunu GitHub üzerinden edinin.

Uygulamanıza Mica veya Akrilik malzeme uygulamak için, SystemBackdrop özelliğini bir XAML SystemBackdrop (genellikle yerleşik arka planlardan biri, MicaBackdrop veya DesktopAcrylicBackdrop) olarak ayarlarsınız.

Bu öğelerin SystemBackdrop özelliği vardır:

Bu örnekler, XAML'de ve kodda sistem arka planı ayarlamayı gösterir.

Mika

Mica genellikle bir uygulama Penceresi için arka plan olarak kullanılır.

<Window
    ... >

    <Window.SystemBackdrop>
        <MicaBackdrop Kind="BaseAlt"/>
    </Window.SystemBackdrop>

</Window>
public MainWindow()
{
    this.InitializeComponent();

    SystemBackdrop = new MicaBackdrop() 
                        { Kind = MicaKind.BaseAlt };
}

Akrilik

Akrilik genellikle geçici kullanıcı arabirimi için açılır menü gibi arka plan olarak kullanılır.

<Flyout
    ... >

    <Flyout.SystemBackdrop>
        <DesktopAcrylicBackdrop/>
    </Flyout.SystemBackdrop>
</Flyout>
Flyout flyout = new Flyout()
{
    SystemBackdrop = new DesktopAcrylicBackdrop()
};

Sistem arka plan denetleyicisini kullanma

Not

Windows Uygulama SDK'sı 1.3 itibaren, önceki bölümde açıklandığı gibi Window.SystemBackdrop özelliğini bir XAML SystemBackdrop olarak ayarlayarak malzeme uygulayabilirsiniz. Bu, bir malzemenin uygulanması için önerilen yoldur.

Bu makalenin geri kalanında, MicaController ve DesktopAcrylicController API'lerinin nasıl kullanılacağı gösterilmektedir.

Uygulamanızda arka plan malzemesi kullanmak için, ISystemBackdropController arabirimini (MicaController veya DesktopAcrylicController) uygulayan denetleyicilerden birini kullanabilirsiniz. Bu sınıflar hem sistem arka planı malzemesinin işlenmesini hem de malzeme için sistem ilkesinin işlenmesini yönetir.

Arka plan malzemeniz olarak Mica'yı kullanmak için bir MicaController nesnesi oluşturun. Akrilik kullanmak için bir DesktopAcrylicController nesnesi oluşturun. Kurulum ve destekleyici kod, her tür sistem arka planı malzemesi için aynıdır.

Bu kod, MicaController'ın nasıl oluşturulacağını gösterir.

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'nın Mica Alt değişkenini kullanmak için bir MicaController nesnesi oluşturun ve Kind özelliğini MicaKind.BaseAltolarak ayarlayın.

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);
        ...
    }
}

Bu kod, DesktopAcrylicController'ın nasıl oluşturulacağını gösterir.

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();
        ...
    }
}

Denetleyici, sisteme varsayılan olarak Açık ve Koyu temalara tepki gösterir. Bu davranışı geçersiz kılmak için denetleyicide aşağıdaki özellikleri ayarlayabilirsiniz:

Not

Denetleyicinin dört özelliğinden herhangi birini özelleştirdikten sonra, ilişkili SystemBackdropConfiguration.Theme değiştiğinde artık varsayılan Açık veya Koyu değerleri uygulamaz. Bu özellikleri yeni temayla eşleşecek şekilde el ile güncelleştirmeniz gerekir.

Uygulamanızda arka plan malzemesini kullanmak için aşağıdaki öğeler gereklidir:

  • Sistem desteği

    Uygulamanın çalıştırıldığı sistem arka plan malzemesini desteklemelidir. Arka plan malzemesinin çalışma zamanında desteklendiğinden emin olmak için MicaController.IsSupported veya DesktopAcrylicController.IsSupported yöntemini çağırın.

  • Geçerli bir hedef

    ICompositionSupportsSystemBackdrop arabirimini uygulayan bir hedef sağlamanız gerekir. XAML uygulamasında XAML Window bu arabirimi uygular ve arka plan hedefi olarak kullanılır.

  • SystemBackdropConfiguration nesnesi

    SystemBackdropConfiguration, sistem arka plan malzemesini düzgün yapılandırmak için sisteme özgü ilke bilgilerini sistem arka planı denetleyicisine sağlar.

  • A DispatcherQueue nesnesini.

    Ana XAML iş parçacığında kullanılabilir bir Windows.System.DispatcherQueue olması gerekir. Örnek koddaki veya WindowsSystemDispatcherQueueHelper sınıfına bakın.

Örnek: Windows AppSDK/WinUI 3 uygulamasında Mica kullanma

Bu örnekte, XAML uygulamasında Mica arka plan malzemesinin nasıl ayarlanacağı gösterilmektedir.

İpucu

Ayrıca GitHub'da şu örnek projelere bakın:

C#: WinUI3 Galerisi'nde SampleSystemBackdropsWindow.

C++/WinRT: Windows Uygulama SDK'sı Mica örneği.

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;
        }
    }
    ...
};
...