Dela via


Använda det visuella lagret med Windows-formulär

Du kan använda API:er för Windows Runtime-komposition (kallas även visuellt lager) i dina Windows Forms-appar för att skapa moderna upplevelser som lyser upp för Windows-användare.

Den fullständiga koden för den här handledningen finns på GitHub: Windows Forms HelloComposition exempel.

Förutsättningar

UWP-värd-API:et har dessa förutsättningar.

Så här använder du API:er för sammansättning i Windows-formulär

I den här självstudien skapar du ett enkelt Användargränssnitt för Windows Forms och lägger till animerade sammansättningselement i det. Både Windows Forms- och Composition-komponenterna hålls enkla, men den interop-kod som visas är densamma oavsett komponenternas komplexitet. Den färdiga appen ser ut så här.

Användargränssnittet för den körande appen

Skapa ett Windows Forms-projekt

Det första steget är att skapa Windows Forms-appprojektet, som innehåller en programdefinition och huvudformuläret för användargränssnittet.

Så här skapar du ett nytt Windows Forms Application-projekt i Visual C# med namnet HelloComposition:

  1. Öppna Visual Studio och välj File>New>Project.
    Dialogrutan Nytt projekt öppnas.
  2. Under kategorin Installerad expanderar du noden Visual C# och väljer sedan Windows Desktop.
  3. Välj mallen Windows Forms App (.NET Framework).
  4. Ange namnet HelloComposition, välj Framework .NET Framework 4.7.2 och klicka sedan på OK.

Visual Studio skapar projektet och öppnar designern för standardprogramfönstret med namnet Form1.cs.

Konfigurera projektet för att använda Windows Runtime-API:er

Om du vill använda Windows Runtime-API:er (WinRT) i din Windows Forms-app måste du konfigurera Visual Studio-projektet för att få åtkomst till Windows Runtime. Dessutom används vektorer i stor utsträckning av API:er för sammansättning, så du måste lägga till de referenser som krävs för att använda vektorer.

NuGet-paket är tillgängliga för att hantera båda dessa behov. Installera de senaste versionerna av dessa paket för att lägga till nödvändiga referenser till projektet.

Anmärkning

Vi rekommenderar att du använder NuGet-paketen för att konfigurera projektet, men du kan lägga till de nödvändiga referenserna manuellt. Mer information finns i Förbättra ditt skrivbordsprogram för Windows. I följande tabell visas de filer som du behöver lägga till referenser till.

Fil Plats
System.Runtime.WindowsRuntime C:\Windows\Microsoft.NET\Framework\v4.0.30319
Windows.Foundation.UniversalApiContract.winmd C:\Program Files (x86)\Windows Kits\10\References<sdk version>\Windows.Foundation.UniversalApiContract<version>
Windows.Foundation.FoundationContract.winmd C:\Program Files (x86)\Windows Kits\10\References<sdk version>\Windows.Foundation.FoundationContract<version>
System.Numerics.Vectors.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Numerics.Vectors\v4.0_4.0.0.0__b03f5f7f11d50a3a
System.Numerics.dll C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.7.2

Skapa en anpassad kontroll för att hantera interop

Om du vill vara värd för innehåll som du skapar med det visuella lagret skapar du en anpassad kontroll som härleds från Kontroll. Den här kontrollen ger dig åtkomst till ett fönster Hantera, som du behöver för att skapa containern för ditt visuella lagerinnehåll.

Det är här du gör det mesta av konfigurationen för att hosta Composition API:er. I den här kontrollen använder du Platform Invocation Services (PInvoke) och COM Interop för att föra in sammansättnings-API:er i din Windows Forms-app. Mer information om PInvoke och COM Interop finns i Interoperera med ohanterad kod.

Tips/Råd

Om du behöver det kontrollerar du den fullständiga koden i slutet av självstudien för att se till att all kod finns på rätt platser när du går igenom självstudien.

  1. Lägg till en ny anpassad kontrollfil i projektet som härleds från Kontroll.

    • Högerklicka på HelloComposition-projektet i Solution Explorer.
    • I snabbmenyn väljer du Lägg till>nytt objekt....
    • I dialogrutan Lägg till nytt objekt väljer du Anpassad kontroll.
    • Namnge kontrollen CompositionHost.cs och klicka sedan på Lägg till. CompositionHost.cs öppnas i designvyn.
  2. Växla till kodvyn för CompositionHost.cs och lägg till följande kod i klassen.

    // Add
    // using Windows.UI.Composition;
    
    IntPtr hwndHost;
    object dispatcherQueue;
    protected ContainerVisual containerVisual;
    protected Compositor compositor;
    
    private ICompositionTarget compositionTarget;
    
    public Visual Child
    {
        set
        {
            if (compositor == null)
            {
                InitComposition(hwndHost);
            }
            compositionTarget.Root = value;
        }
    }
    
  3. Lägg till kod i konstruktorn.

    I konstruktorn anropar du metoderna InitializeCoreDispatcher och InitComposition . Du skapar dessa metoder i nästa steg.

    public CompositionHost()
    {
        InitializeComponent();
    
        // Get the window handle.
        hwndHost = Handle;
    
        // Create dispatcher queue.
        dispatcherQueue = InitializeCoreDispatcher();
    
        // Build Composition tree of content.
        InitComposition(hwndHost);
    }
    
  4. Initiera en tråd med en CoreDispatcher. Kärnutskickaren ansvarar för att bearbeta fönstermeddelanden och skicka händelser för WinRT-API:er. Nya instanser av Compositor måste skapas på en tråd som har en CoreDispatcher.

    • Skapa en metod med namnet InitializeCoreDispatcher och lägg till kod för att konfigurera dispatcher-kön.
    // Add
    // using System.Runtime.InteropServices;
    
    private object InitializeCoreDispatcher()
    {
        DispatcherQueueOptions options = new DispatcherQueueOptions();
        options.apartmentType = DISPATCHERQUEUE_THREAD_APARTMENTTYPE.DQTAT_COM_STA;
        options.threadType = DISPATCHERQUEUE_THREAD_TYPE.DQTYPE_THREAD_CURRENT;
        options.dwSize = Marshal.SizeOf(typeof(DispatcherQueueOptions));
    
        object queue = null;
        CreateDispatcherQueueController(options, out queue);
        return queue;
    }
    
    • Dispatcher-kön kräver en PInvoke-deklaration. Placera den här deklarationen i slutet av koden för klassen. (Vi placerar den här koden i en region för att hålla klasskoden snygg.)
    #region PInvoke declarations
    
    //typedef enum DISPATCHERQUEUE_THREAD_APARTMENTTYPE
    //{
    //    DQTAT_COM_NONE,
    //    DQTAT_COM_ASTA,
    //    DQTAT_COM_STA
    //};
    internal enum DISPATCHERQUEUE_THREAD_APARTMENTTYPE
    {
        DQTAT_COM_NONE = 0,
        DQTAT_COM_ASTA = 1,
        DQTAT_COM_STA = 2
    };
    
    //typedef enum DISPATCHERQUEUE_THREAD_TYPE
    //{
    //    DQTYPE_THREAD_DEDICATED,
    //    DQTYPE_THREAD_CURRENT
    //};
    internal enum DISPATCHERQUEUE_THREAD_TYPE
    {
        DQTYPE_THREAD_DEDICATED = 1,
        DQTYPE_THREAD_CURRENT = 2,
    };
    
    //struct DispatcherQueueOptions
    //{
    //    DWORD dwSize;
    //    DISPATCHERQUEUE_THREAD_TYPE threadType;
    //    DISPATCHERQUEUE_THREAD_APARTMENTTYPE apartmentType;
    //};
    [StructLayout(LayoutKind.Sequential)]
    internal struct DispatcherQueueOptions
    {
        public int dwSize;
    
        [MarshalAs(UnmanagedType.I4)]
        public DISPATCHERQUEUE_THREAD_TYPE threadType;
    
        [MarshalAs(UnmanagedType.I4)]
        public DISPATCHERQUEUE_THREAD_APARTMENTTYPE apartmentType;
    };
    
    //HRESULT CreateDispatcherQueueController(
    //  DispatcherQueueOptions options,
    //  ABI::Windows::System::IDispatcherQueueController** dispatcherQueueController
    //);
    [DllImport("coremessaging.dll", EntryPoint = "CreateDispatcherQueueController", CharSet = CharSet.Unicode)]
    internal static extern IntPtr CreateDispatcherQueueController(DispatcherQueueOptions options,
                                            [MarshalAs(UnmanagedType.IUnknown)]
                                            out object dispatcherQueueController);
    
    #endregion PInvoke declarations
    

    Nu har du dispatcher-kön redo och kan börja initiera och skapa innehåll för komposition.

  5. Initiera Kompositören. Compositor är en fabrik som skapar en mängd olika typer i namnområdet Windows.UI.Composition som sträcker sig över det visuella lagret, effektsystemet och animeringssystemet. Klassen Compositor hanterar också livslängden för objekt som skapats från fabriken.

    private void InitComposition(IntPtr hwndHost)
    {
        ICompositorDesktopInterop interop;
    
        compositor = new Compositor();
        object iunknown = compositor as object;
        interop = (ICompositorDesktopInterop)iunknown;
        IntPtr raw;
        interop.CreateDesktopWindowTarget(hwndHost, true, out raw);
    
        object rawObject = Marshal.GetObjectForIUnknown(raw);
        compositionTarget = (ICompositionTarget)rawObject;
    
        if (raw == null) { throw new Exception("QI Failed"); }
    
        containerVisual = compositor.CreateContainerVisual();
        Child = containerVisual;
    }
    
    • ICompositorDesktopInterop och ICompositionTarget kräver COM-importer. Placera den här koden efter klassen CompositionHost , men i namnområdesdeklarationen.
    #region COM Interop
    
    /*
    #undef INTERFACE
    #define INTERFACE ICompositorDesktopInterop
        DECLARE_INTERFACE_IID_(ICompositorDesktopInterop, IUnknown, "29E691FA-4567-4DCA-B319-D0F207EB6807")
        {
            IFACEMETHOD(CreateDesktopWindowTarget)(
                _In_ HWND hwndTarget,
                _In_ BOOL isTopmost,
                _COM_Outptr_ IDesktopWindowTarget * *result
                ) PURE;
        };
    */
    [ComImport]
    [Guid("29E691FA-4567-4DCA-B319-D0F207EB6807")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface ICompositorDesktopInterop
    {
        void CreateDesktopWindowTarget(IntPtr hwndTarget, bool isTopmost, out IntPtr test);
    }
    
    //[contract(Windows.Foundation.UniversalApiContract, 2.0)]
    //[exclusiveto(Windows.UI.Composition.CompositionTarget)]
    //[uuid(A1BEA8BA - D726 - 4663 - 8129 - 6B5E7927FFA6)]
    //interface ICompositionTarget : IInspectable
    //{
    //    [propget] HRESULT Root([out] [retval] Windows.UI.Composition.Visual** value);
    //    [propput] HRESULT Root([in] Windows.UI.Composition.Visual* value);
    //}
    
    [ComImport]
    [Guid("A1BEA8BA-D726-4663-8129-6B5E7927FFA6")]
    [InterfaceType(ComInterfaceType.InterfaceIsIInspectable)]
    public interface ICompositionTarget
    {
        Windows.UI.Composition.Visual Root
        {
            get;
            set;
        }
    }
    
    #endregion COM Interop
    

Skapa en anpassad kontroll för att vara värd för sammansättningselement

Det är en bra idé att placera koden som genererar och hanterar dina kompositionselement i en separat kontroll som härleds från CompositionHost. Det gör att interop-koden som du skapade i klassen CompositionHost kan återanvändas.

Här skapar du en anpassad kontroll som härleds från CompositionHost. Den här kontrollen läggs till i Visual Studio-verktygslådan så att du kan lägga till den i formuläret.

  1. Lägg till en ny anpassad kontrollfil i projektet som härleds från CompositionHost.

    • Högerklicka på HelloComposition-projektet i Solution Explorer.
    • I snabbmenyn väljer du Lägg till>nytt objekt....
    • I dialogrutan Lägg till nytt objekt väljer du Anpassad kontroll.
    • Ge kontrollen namnet CompositionHostControl.cs och klicka sedan på Lägg till. CompositionHostControl.cs öppnas i designvyn.
  2. I fönstret Egenskaper för CompositionHostControl.cs designvy anger du egenskapen BackColor till ControlLight.

    Det är valfritt att ange bakgrundsfärgen. Vi gör det här så att du kan se din anpassade kontroll mot formulärbakgrunden.

  3. Växla till kodvyn för CompositionHostControl.cs och uppdatera klassdeklarationen så att den härleds från CompositionHost.

    class CompositionHostControl : CompositionHost
    
  4. Uppdatera konstruktorn för att anropa baskonstruktorn.

    public CompositionHostControl() : base()
    {
    
    }
    

Lägga till sammansättningselement

Med infrastrukturen på plats kan du nu lägga till sammansättningsinnehåll i appens användargränssnitt.

I det här exemplet lägger du till kod i klassen CompositionHostControl som skapar och animerar en enkel SpriteVisual.

  1. Lägg till ett kompositionselement.

    I CompositionHostControl.cs lägger du till dessa metoder i klassen CompositionHostControl.

    // Add
    // using Windows.UI.Composition;
    
    public void AddElement(float size, float offsetX, float offsetY)
    {
        var visual = compositor.CreateSpriteVisual();
        visual.Size = new Vector2(size, size); // Requires references
        visual.Brush = compositor.CreateColorBrush(GetRandomColor());
        visual.Offset = new Vector3(offsetX, offsetY, 0);
        containerVisual.Children.InsertAtTop(visual);
    
        AnimateSquare(visual, 3);
    }
    
    private void AnimateSquare(SpriteVisual visual, int delay)
    {
        float offsetX = (float)(visual.Offset.X);
        Vector3KeyFrameAnimation animation = compositor.CreateVector3KeyFrameAnimation();
        float bottom = Height - visual.Size.Y;
        animation.InsertKeyFrame(1f, new Vector3(offsetX, bottom, 0f));
        animation.Duration = TimeSpan.FromSeconds(2);
        animation.DelayTime = TimeSpan.FromSeconds(delay);
        visual.StartAnimation("Offset", animation);
    }
    
    private Windows.UI.Color GetRandomColor()
    {
        Random random = new Random();
        byte r = (byte)random.Next(0, 255);
        byte g = (byte)random.Next(0, 255);
        byte b = (byte)random.Next(0, 255);
        return Windows.UI.Color.FromArgb(255, r, g, b);
    }
    

Lägg till kontrollen i formuläret

Nu när du har en anpassad kontroll som värd för sammansättningsinnehåll kan du lägga till det i appens användargränssnitt. Här lägger du till en instans av CompositionHostControl som du skapade i föregående steg. CompositionHostControl läggs automatiskt till i Visual Studio-verktygslådan under projektnamnet Komponenter.

  1. I Form1.CS designvyn lägger du till en knapp i användargränssnittet.

    • Dra en knapp från verktygslådan till Formulär1. Placera den i formulärets övre vänstra hörn. (Se bilden i början av självstudien för att kontrollera placeringen av kontrollerna.)
    • I fönstret Egenskaper ändrar du egenskapen Text från button1 till Lägg till kompositionselement.
    • Ändra storlek på knappen så att all text visas.

    (Mer information finns i Så här lägger du till kontroller i Windows-formulär.)

  2. Lägg till en CompositionHostControl i användargränssnittet.

    • Dra en CompositionHostControl från verktygslådan till Form1. Placera den till höger om knappen.
    • Ändra storlek på CompositionHost så att resten av formuläret fylls.
  3. Hantera knappklickshändelsen.

    • I fönstret Egenskaper klickar du på blixten för att växla till vyn Händelser.
    • I händelselistan, välj händelsen Klicka, skriv Button_Clickoch tryck på Enter.
    • Den här koden läggs till i Form1.cs:
    private void Button_Click(object sender, EventArgs e)
    {
    
    }
    
  4. Lägg till kod i knappklickshanteraren för att skapa nya element.

    • I Form1.cs lägger du till kod i den Button_Click händelsehanterare som du skapade tidigare. Den här koden anropar CompositionHostControl1.AddElement för att skapa ett nytt element med en slumpmässigt genererad storlek och förskjutning. (Instansen av CompositionHostControl fick automatiskt namnet compositionHostControl1 när du drog den till formuläret.)
    // Add
    // using System;
    
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Random random = new Random();
        float size = random.Next(50, 150);
        float offsetX = random.Next(0, (int)(compositionHostControl1.Width - size));
        float offsetY = random.Next(0, (int)(compositionHostControl1.Height/2 - size));
        compositionHostControl1.AddElement(size, offsetX, offsetY);
    }
    

Nu kan du skapa och köra din Windows Forms-app. När du klickar på knappen bör du se animerade rutor som lagts till i användargränssnittet.

Nästa steg

Ett mer komplett exempel som bygger på samma infrastruktur finns i integreringsexemplet för Visual Layer i Windows Forms på GitHub.

Ytterligare resurser

Fullständig kod

Här är den fullständiga koden för den här handledningen.

Form1.cs

using System;
using System.Windows.Forms;

namespace HelloComposition
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, EventArgs e)
        {
            Random random = new Random();
            float size = random.Next(50, 150);
            float offsetX = random.Next(0, (int)(compositionHostControl1.Width - size));
            float offsetY = random.Next(0, (int)(compositionHostControl1.Height/2 - size));
            compositionHostControl1.AddElement(size, offsetX, offsetY);
        }
    }
}

CompositionHostControl.cs

using System;
using System.Numerics;
using Windows.UI.Composition;

namespace HelloComposition
{
    class CompositionHostControl : CompositionHost
    {
        public CompositionHostControl() : base()
        {

        }

        public void AddElement(float size, float offsetX, float offsetY)
        {
            var visual = compositor.CreateSpriteVisual();
            visual.Size = new Vector2(size, size); // Requires references
            visual.Brush = compositor.CreateColorBrush(GetRandomColor());
            visual.Offset = new Vector3(offsetX, offsetY, 0);
            containerVisual.Children.InsertAtTop(visual);

            AnimateSquare(visual, 3);
        }

        private void AnimateSquare(SpriteVisual visual, int delay)
        {
            float offsetX = (float)(visual.Offset.X);
            Vector3KeyFrameAnimation animation = compositor.CreateVector3KeyFrameAnimation();
            float bottom = Height - visual.Size.Y;
            animation.InsertKeyFrame(1f, new Vector3(offsetX, bottom, 0f));
            animation.Duration = TimeSpan.FromSeconds(2);
            animation.DelayTime = TimeSpan.FromSeconds(delay);
            visual.StartAnimation("Offset", animation);
        }

        private Windows.UI.Color GetRandomColor()
        {
            Random random = new Random();
            byte r = (byte)random.Next(0, 255);
            byte g = (byte)random.Next(0, 255);
            byte b = (byte)random.Next(0, 255);
            return Windows.UI.Color.FromArgb(255, r, g, b);
        }
    }
}

CompositionHost.cs

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Windows.UI.Composition;

namespace HelloComposition
{
    public partial class CompositionHost : Control
    {
        IntPtr hwndHost;
        object dispatcherQueue;
        protected ContainerVisual containerVisual;
        protected Compositor compositor;
        private ICompositionTarget compositionTarget;

        public Visual Child
        {
            set
            {
                if (compositor == null)
                {
                    InitComposition(hwndHost);
                }
                compositionTarget.Root = value;
            }
        }

        public CompositionHost()
        {
            // Get the window handle.
            hwndHost = Handle;

            // Create dispatcher queue.
            dispatcherQueue = InitializeCoreDispatcher();

            // Build Composition tree of content.
            InitComposition(hwndHost);
        }

        private object InitializeCoreDispatcher()
        {
            DispatcherQueueOptions options = new DispatcherQueueOptions();
            options.apartmentType = DISPATCHERQUEUE_THREAD_APARTMENTTYPE.DQTAT_COM_STA;
            options.threadType = DISPATCHERQUEUE_THREAD_TYPE.DQTYPE_THREAD_CURRENT;
            options.dwSize = Marshal.SizeOf(typeof(DispatcherQueueOptions));

            object queue = null;
            CreateDispatcherQueueController(options, out queue);
            return queue;
        }

        private void InitComposition(IntPtr hwndHost)
        {
            ICompositorDesktopInterop interop;

            compositor = new Compositor();
            object iunknown = compositor as object;
            interop = (ICompositorDesktopInterop)iunknown;
            IntPtr raw;
            interop.CreateDesktopWindowTarget(hwndHost, true, out raw);

            object rawObject = Marshal.GetObjectForIUnknown(raw);
            compositionTarget = (ICompositionTarget)rawObject;

            if (raw == null) { throw new Exception("QI Failed"); }

            containerVisual = compositor.CreateContainerVisual();
            Child = containerVisual;
        }

        protected override void OnPaint(PaintEventArgs pe)
        {
            base.OnPaint(pe);
        }

        #region PInvoke declarations

        //typedef enum DISPATCHERQUEUE_THREAD_APARTMENTTYPE
        //{
        //    DQTAT_COM_NONE,
        //    DQTAT_COM_ASTA,
        //    DQTAT_COM_STA
        //};
        internal enum DISPATCHERQUEUE_THREAD_APARTMENTTYPE
        {
            DQTAT_COM_NONE = 0,
            DQTAT_COM_ASTA = 1,
            DQTAT_COM_STA = 2
        };

        //typedef enum DISPATCHERQUEUE_THREAD_TYPE
        //{
        //    DQTYPE_THREAD_DEDICATED,
        //    DQTYPE_THREAD_CURRENT
        //};
        internal enum DISPATCHERQUEUE_THREAD_TYPE
        {
            DQTYPE_THREAD_DEDICATED = 1,
            DQTYPE_THREAD_CURRENT = 2,
        };

        //struct DispatcherQueueOptions
        //{
        //    DWORD dwSize;
        //    DISPATCHERQUEUE_THREAD_TYPE threadType;
        //    DISPATCHERQUEUE_THREAD_APARTMENTTYPE apartmentType;
        //};
        [StructLayout(LayoutKind.Sequential)]
        internal struct DispatcherQueueOptions
        {
            public int dwSize;

            [MarshalAs(UnmanagedType.I4)]
            public DISPATCHERQUEUE_THREAD_TYPE threadType;

            [MarshalAs(UnmanagedType.I4)]
            public DISPATCHERQUEUE_THREAD_APARTMENTTYPE apartmentType;
        };

        //HRESULT CreateDispatcherQueueController(
        //  DispatcherQueueOptions options,
        //  ABI::Windows::System::IDispatcherQueueController** dispatcherQueueController
        //);
        [DllImport("coremessaging.dll", EntryPoint = "CreateDispatcherQueueController", CharSet = CharSet.Unicode)]
        internal static extern IntPtr CreateDispatcherQueueController(DispatcherQueueOptions options,
                                                 [MarshalAs(UnmanagedType.IUnknown)]
                                        out object dispatcherQueueController);

        #endregion PInvoke declarations
    }

    #region COM Interop

    /*
    #undef INTERFACE
    #define INTERFACE ICompositorDesktopInterop
        DECLARE_INTERFACE_IID_(ICompositorDesktopInterop, IUnknown, "29E691FA-4567-4DCA-B319-D0F207EB6807")
        {
            IFACEMETHOD(CreateDesktopWindowTarget)(
                _In_ HWND hwndTarget,
                _In_ BOOL isTopmost,
                _COM_Outptr_ IDesktopWindowTarget * *result
                ) PURE;
        };
    */
    [ComImport]
    [Guid("29E691FA-4567-4DCA-B319-D0F207EB6807")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface ICompositorDesktopInterop
    {
        void CreateDesktopWindowTarget(IntPtr hwndTarget, bool isTopmost, out IntPtr test);
    }

    //[contract(Windows.Foundation.UniversalApiContract, 2.0)]
    //[exclusiveto(Windows.UI.Composition.CompositionTarget)]
    //[uuid(A1BEA8BA - D726 - 4663 - 8129 - 6B5E7927FFA6)]
    //interface ICompositionTarget : IInspectable
    //{
    //    [propget] HRESULT Root([out] [retval] Windows.UI.Composition.Visual** value);
    //    [propput] HRESULT Root([in] Windows.UI.Composition.Visual* value);
    //}

    [ComImport]
    [Guid("A1BEA8BA-D726-4663-8129-6B5E7927FFA6")]
    [InterfaceType(ComInterfaceType.InterfaceIsIInspectable)]
    public interface ICompositionTarget
    {
        Windows.UI.Composition.Visual Root
        {
            get;
            set;
        }
    }
    #endregion COM Interop
}