Utilisation de la couche visuelle avec le contenu XAMLUsing the Visual Layer with XAML

La plupart des applications qui utilisent des fonctionnalités de couche visuelle font appel à l’infrastructure XAML pour définir le contenu d’interface utilisateur principal.Most apps that consume Visual Layer capabilities will use XAML to define the main UI content. Dans la mise à jour anniversaire Windows 10, il existe de nouvelles fonctionnalités dans l’infrastructure XAML et la couche visuelle qui facilitent la combinaison de ces deux technologies pour créer des expériences utilisateur incroyables.In the Windows 10 Anniversary Update, there are new features in the XAML framework and the Visual Layer that make it easier to combine these two technologies to create stunning user experiences. Les fonctionnalités XAML et d’interopérabilité des couches visuelles peuvent être utilisées pour créer des animations et des effets avancés non disponibles à l’aide des API XAML seules.XAML and Visual Layer interop functionality can be used to create advanced animations and effects not available using XAML APIs alone. notamment :This includes:

  • Effets de pinceau comme flou et verre dépoliBrush effects like blur and frosted glass
  • Effets d’éclairage dynamiqueDynamic lighting effects
  • Parallaxe et animations par défilementScroll driven animations and parallax
  • Animations de disposition automatiqueAutomatic layout animations
  • Pixel-ombres de dépôt parfaitePixel-perfect drop shadows

Ces effets et animations peuvent être appliqués au contenu XAML existant. vous n’avez donc pas à restructurer radicalement votre application XAML pour tirer parti de la nouvelle fonctionnalité.These effects and animations can be applied to existing XAML content, so you don't have to dramatically restructure your XAML app to take advantage of the new functionality. Les animations de disposition, les ombres et les effets de flou sont abordés dans la section Recettes ci-après.Layout animations, shadows, and blur effects are covered in the Recipes section below. Pour obtenir un exemple de code implémentant la parallaxe, consultez l’exemple ParallaxingListItems.For a code sample implementing parallax, see the ParallaxingListItems sample. Le référentiel WindowsUIDevLabs comprend également plusieurs exemples pour implémenter des animations, des ombres et des effets.The WindowsUIDevLabs repository also has several other samples for implementing animations, shadows and effects.

La classe XamlCompositionBrushBaseThe XamlCompositionBrushBase class

XamlCompositionBrush fournit une classe de base pour les pinceaux XAML qui peignent une zone avec un CompositionBrush.XamlCompositionBrush provides a base class for XAML brushes that paint an area with a CompositionBrush. Cela peut être utilisé pour appliquer facilement des effets de composition comme un flou ou un verre dépoli aux éléments d’interface utilisateur XAML.This can be used to easily apply composition effects like blur or frosted glass to XAML UI elements.

Consultez la section pinceaux pour plus d’informations sur l’utilisation de pinceaux avec l’interface utilisateur XAML.See the Brushes section for more info on using brushes with XAML UI.

Pour obtenir des exemples de code, consultez la page de référence de la classe XamlCompositionBrushBase.For code examples, see the reference page for XamlCompositionBrushBase.

La classe XamlLightThe XamlLight class

XamlLight fournit une classe de base pour les effets d’éclairage XAML qui illuminent dynamiquement une zone avec un CompositionLight.XamlLight provides a base class for XAML lighting effects that dynamically light an area with a CompositionLight.

Pour plus d’informations sur l’utilisation d’éclairages, consultez la section éclairage , y compris les éléments d’interface utilisateur XAML.See the Lighting section for more info on using lights, including lighting XAML UI elements.

Pour obtenir des exemples de code, consultez la page de référence de XamlLight.For code examples, see the reference page for XamlLight.

La classe ElementCompositionPreviewThe ElementCompositionPreview class

ElementCompositionPreview est une classe statique qui fournit une fonctionnalité d’interopérabilité entre l’infrastructure XAML et la couche visuelle.ElementCompositionPreview is a static class that provides XAML and Visual Layer interop functionality. Pour une vue d’ensemble de la couche visuelle et de ses fonctionnalités, consultez Couche visuelle.For an overview of the Visual Layer and its functionality, see Visual Layer. La classe ElementCompositionPreview propose les méthodes suivantes :The ElementCompositionPreview class provides the following methods:

  • GetElementVisual: obtenir un visuel « document » utilisé pour restituer cet élémentGetElementVisual: Get a "handout" Visual that is used to render this element
  • SetElementChildVisual: définit un visuel « main » comme dernier enfant de l’arborescence d’éléments visuels de cet élément.SetElementChildVisual: Sets a "handin" Visual as the last child of this element’s visual tree. Ce visuel pourra dessiner par-dessus le reste de l’élément.This Visual will draw on top of the rest of the element.
  • GetElementChildVisual : récupérez le visuel défini à l’aide de SetElementChildVisual.GetElementChildVisual: Retrieve the Visual set using SetElementChildVisual
  • GetScrollViewerManipulationPropertySet : obtenez un objet permettant de créer des animations de 60 FPS en fonction du décalage de défilement dans un élément ScrollViewer.GetScrollViewerManipulationPropertySet: Get an object that can be used to create 60fps animations based on scroll offset in a ScrollViewer

Remarques sur ElementCompositionPreview.GetElementVisualRemarks on ElementCompositionPreview.GetElementVisual

ElementCompositionPreview.GetElementVisual renvoie un visuel de « document » qui est utilisé pour générer l’élément UIElement donné.ElementCompositionPreview.GetElementVisual returns a “handout” Visual that is used to render the given UIElement. Les propriétés telles que Visual.Opacity, Visual.Offset et Visual.Size sont définies par l’infrastructure XAML en fonction de l’état de l’élément UIElement.Properties such as Visual.Opacity, Visual.Offset, and Visual.Size are set by the XAML framework based on the state of the UIElement. Cela permet d’activer des techniques telles que les animations de repositionnement implicite (consultez Recettes).This enables techniques such as implicit reposition animations (see Recipes).

Notez que, dans la mesure où les éléments Offset et Size sont définis comme le résultat d’une disposition d’infrastructure XAML, les développeurs doivent être prudents lors de la modification ou de l’animation de ces propriétés.Note that since Offset and Size are set as the result of XAML framework layout, developers should be careful when modifying or animating these properties. Les développeurs doivent uniquement modifier ou animer un élément Offset lorsque l’angle supérieur gauche de l’élément a la même position que celle de son parent dans la disposition.Developers should only modify or animate Offset when the element’s top-left corner has the same position as that of its parent in layout. L’élément Size ne doit généralement pas être modifié, mais accéder à la propriété peut être utile.Size should generally not be modified, but accessing the property may be useful. Par exemple, les exemples d’ombre portée et de verre givré ci-dessous utilisent la propriété Size d’un visuel de document comme entrée d’une animation.For example, the Drop Shadow and Frosted Glass samples below use Size of a handout Visual as input to an animation.

Notez également que les propriétés mises à jour de visuel de document ne seront pas reflétées dans l’élément UIElement correspondant.As an additional caveat, updated properties of the handout Visual will not be reflected in the corresponding UIElement. Ainsi, quand vous définissez par exemple UIElement.Opacity sur 0,5, la propriété Opacity du visuel de document correspondant sera définie sur 0,5.So for example, setting UIElement.Opacity to 0.5 will set the corresponding handout Visual’s Opacity to 0.5. Cependant, définir la propriété Opacity du visuel de document sur 0,5 entraînera l’affichage du contenu avec une opacité de 50 %, mais ne modifiera pas la valeur de propriété Opacity de l’élément UIElement correspondant.However, setting the handout Visual’s Opacity to 0.5 will cause the content to appear at 50% opacity, but will not change the value of the corresponding UIElement’s Opacity property.

Exemple d’animation OffsetExample of Offset animation

IncorrectIncorrect

<Border>
      <Image x:Name="MyImage" Margin="5" />
</Border>
// Doesn’t work because Image has a margin!
ElementCompositionPreview.GetElementVisual(MyImage).StartAnimation("Offset", parallaxAnimation);

CorrectCorrect

<Border>
    <Canvas Margin="5">
        <Image x:Name="MyImage" />
    </Canvas>
</Border>
// This works because the Canvas parent doesn’t generate a layout offset.
ElementCompositionPreview.GetElementVisual(MyImage).StartAnimation("Offset", parallaxAnimation);

La méthode ElementCompositionPreview.SetElementChildVisualThe ElementCompositionPreview.SetElementChildVisual method

ElementCompositionPreview.SetElementChildVisual permet aux développeurs de fournir un visuel d’élément qui s’affichera comme composant de l’arborescence visuelle d’un élément.ElementCompositionPreview.SetElementChildVisual allows the developer to supply a “handin” Visual that will appear as part of an element’s Visual Tree. Cela permet aux développeurs de créer une « île de composition » où le contenu visuel peut s’afficher dans une interface utilisateur XAML.This allows developers to create a “Composition Island” where Visual-based content can appear inside a XAML UI. Les développeurs doivent être prudents avec l’utilisation de cette technique dans la mesure où le contenu visuel ne bénéficiera pas des mêmes accessibilité et garanties d’expérience utilisateur que le contenu XAML.Developers should be conservative about using this technique because Visual-based content will not have the same accessibility and user experience guarantees of XAML content. Par conséquent, il est généralement recommandé d’utiliser cette technique uniquement lorsque cela est nécessaire pour implémenter des effets personnalisés tels que ceux disponibles dans la section Recettes ci-dessous.Therefore, it is generally recommended that this technique only be used when necessary to implement custom effects such as those found in the Recipes section below.

Méthodes GetAlphaMaskGetAlphaMask methods

Les éléments Image, TextBlock et Shape implémentent chacun une méthode appelée GetAlphaMask qui renvoie un élément CompositionBrush représentant une image en nuances de gris avec la forme de l’élément.Image, TextBlock, and Shape each implement a method called GetAlphaMask that returns a CompositionBrush representing a grayscale image with the shape of the element. Cet élément CompositionBrush peut servir d’entrée pour une Composition DropShadow, de sorte que l’ombre puisse refléter la forme de l’élément plutôt qu’un rectangle.This CompositionBrush can serve as an input for a Composition DropShadow, so the shadow can reflect the shape of the element instead of a rectangle. Cela permet d’obtenir des ombres de contour au pixel près pour le texte, les images avec masque alpha et les formes.This enables pixel perfect, contour-based shadows for text, images with alpha, and shapes. Consultez la section Ombre portée ci-dessous pour obtenir un exemple de cette API.See Drop Shadow below for an example of this API.

RecettesRecipes

Animation de repositionnementReposition animation

À l’aide des animations implicites de composition, un développeur peut automatiquement animer les changements d’une disposition d’élément par rapport à son parent.Using Composition Implicit Animations, a developer can automatically animate changes in an element’s layout relative to its parent. Par exemple, si vous modifiez la propriété Margin du bouton ci-dessous, il s’anime automatiquement pour rejoindre sa nouvelle position de disposition.For example, if you change the Margin of the button below, it will automatically animate to its new layout position.

Vue d’ensemble de l’implémentationImplementation overview

  1. Obtenir le visuel de document pour l’élément cibleGet the handout Visual for the target element
  2. Créer un élément ImplicitAnimationCollection qui anime automatiquement les modifications dans la propriété OffsetCreate an ImplicitAnimationCollection that automatically animates changes in the Offset property
  3. Associer l’élément ImplicitAnimationCollection au visuel de stockageAssociate the ImplicitAnimationCollection with the backing Visual
<Button x:Name="RepositionTarget" Content="Click Me" />
public MainPage()
{
    InitializeComponent();
    InitializeRepositionAnimation(RepositionTarget);
}

private void InitializeRepositionAnimation(UIElement repositionTarget)
{
    var targetVisual = ElementCompositionPreview.GetElementVisual(repositionTarget);
    Compositor compositor = targetVisual.Compositor;

    // Create an animation to animate targetVisual's Offset property to its final value
    var repositionAnimation = compositor.CreateVector3KeyFrameAnimation();
    repositionAnimation.Duration = TimeSpan.FromSeconds(0.66);
    repositionAnimation.Target = "Offset";
    repositionAnimation.InsertExpressionKeyFrame(1.0f, "this.FinalValue");

    // Run this animation when the Offset Property is changed
    var repositionAnimations = compositor.CreateImplicitAnimationCollection();
    repositionAnimations["Offset"] = repositionAnimation;

    targetVisual.ImplicitAnimations = repositionAnimations;
}

Ombre portéeDrop shadow

Appliquez une ombre portée au pixel près à un élément UIElement, par exemple un élément Ellipse contenant une image.Apply a pixel-perfect drop shadow to a UIElement, for example an Ellipse containing a picture. Étant donné que l’ombre exige qu’un élément SpriteVisual soit créé par l’application, nous devons créer un élément « hôte » qui contient l’élément SpriteVisual à l’aide de ElementCompositionPreview.SetElementChildVisual.Since the shadow requires a SpriteVisual created by the app, we need to create a “host” element which will contain the SpriteVisual using ElementCompositionPreview.SetElementChildVisual.

Vue d’ensemble de l’implémentationImplementation overview

  1. Obtenir le visuel de document pour l’élément hôteGet the handout Visual for the host element
  2. Créer un élément Windows.UI.Composition DropShadowCreate a Windows.UI.Composition DropShadow
  3. Configurer l’élément DropShadow pour obtenir sa forme à partir de l’élément cible via un masqueConfigure the DropShadow to get its shape from the target element via a mask
    • L’élément DropShadow est rectangulaire par défaut, cette étape n’est donc pas nécessaire si la cible est rectangulaireDropShadow is rectangular by default, so this is not necessary if the target is rectangular
  4. Attacher l’ombre à un nouvel élément SpriteVisual et définir l’élément SpriteVisual comme l’enfant de l’élément hôteAttach shadow to a new SpriteVisual, and set the SpriteVisual as the child of the host element
  5. Lier la taille de l’élément SpriteVisual à la taille de l’hôte en utilisant une ExpressionAnimationBind size of the SpriteVisual to the size of the host using an ExpressionAnimation
<Grid Width="200" Height="200">
    <Canvas x:Name="ShadowHost" />
    <Ellipse x:Name="CircleImage">
        <Ellipse.Fill>
            <ImageBrush ImageSource="Assets/Images/2.jpg" Stretch="UniformToFill" />
        </Ellipse.Fill>
    </Ellipse>
</Grid>
public MainPage()
{
    InitializeComponent();
    InitializeDropShadow(ShadowHost, CircleImage);
}

private void InitializeDropShadow(UIElement shadowHost, Shape shadowTarget)
{
    Visual hostVisual = ElementCompositionPreview.GetElementVisual(shadowHost);
    Compositor compositor = hostVisual.Compositor;

    // Create a drop shadow
    var dropShadow = compositor.CreateDropShadow();
    dropShadow.Color = Color.FromArgb(255, 75, 75, 80);
    dropShadow.BlurRadius = 15.0f;
    dropShadow.Offset = new Vector3(2.5f, 2.5f, 0.0f);
    // Associate the shape of the shadow with the shape of the target element
    dropShadow.Mask = shadowTarget.GetAlphaMask();

    // Create a Visual to hold the shadow
    var shadowVisual = compositor.CreateSpriteVisual();
    shadowVisual.Shadow = dropShadow;

    // Add the shadow as a child of the host in the visual tree
   ElementCompositionPreview.SetElementChildVisual(shadowHost, shadowVisual);

    // Make sure size of shadow host and shadow visual always stay in sync
    var bindSizeAnimation = compositor.CreateExpressionAnimation("hostVisual.Size");
    bindSizeAnimation.SetReferenceParameter("hostVisual", hostVisual);

    shadowVisual.StartAnimation("Size", bindSizeAnimation);
}

Les deux listes suivantes illustrent les équivalents c++/WinRT et c++/CX du code précédent du# C à l’aide de la même structure XAML.The following two listings show the C++/WinRT and C++/CX equivalents of the previous C# code using the same XAML structure.

#include <winrt/Windows.UI.Composition.h>
#include <winrt/Windows.UI.Xaml.h>
#include <winrt/Windows.UI.Xaml.Hosting.h>
#include <winrt/Windows.UI.Xaml.Shapes.h>
...
MainPage()
{
    InitializeComponent();
    InitializeDropShadow(ShadowHost(), CircleImage());
}

int32_t MyProperty();
void MyProperty(int32_t value);

void InitializeDropShadow(Windows::UI::Xaml::UIElement const& shadowHost, Windows::UI::Xaml::Shapes::Shape const& shadowTarget)
{
    auto hostVisual{ Windows::UI::Xaml::Hosting::ElementCompositionPreview::GetElementVisual(shadowHost) };
    auto compositor{ hostVisual.Compositor() };

    // Create a drop shadow
    auto dropShadow{ compositor.CreateDropShadow() };
    dropShadow.Color(Windows::UI::ColorHelper::FromArgb(255, 75, 75, 80));
    dropShadow.BlurRadius(15.0f);
    dropShadow.Offset(Windows::Foundation::Numerics::float3{ 2.5f, 2.5f, 0.0f });
    // Associate the shape of the shadow with the shape of the target element
    dropShadow.Mask(shadowTarget.GetAlphaMask());

    // Create a Visual to hold the shadow
    auto shadowVisual = compositor.CreateSpriteVisual();
    shadowVisual.Shadow(dropShadow);

    // Add the shadow as a child of the host in the visual tree
    Windows::UI::Xaml::Hosting::ElementCompositionPreview::SetElementChildVisual(shadowHost, shadowVisual);

    // Make sure size of shadow host and shadow visual always stay in sync
    auto bindSizeAnimation{ compositor.CreateExpressionAnimation(L"hostVisual.Size") };
    bindSizeAnimation.SetReferenceParameter(L"hostVisual", hostVisual);

    shadowVisual.StartAnimation(L"Size", bindSizeAnimation);
}
#include "WindowsNumerics.h"

MainPage::MainPage()
{
    InitializeComponent();
    InitializeDropShadow(ShadowHost, CircleImage);
}

void MainPage::InitializeDropShadow(Windows::UI::Xaml::UIElement^ shadowHost, Windows::UI::Xaml::Shapes::Shape^ shadowTarget)
{
    auto hostVisual = Windows::UI::Xaml::Hosting::ElementCompositionPreview::GetElementVisual(shadowHost);
    auto compositor = hostVisual->Compositor;

    // Create a drop shadow
    auto dropShadow = compositor->CreateDropShadow();
    dropShadow->Color = Windows::UI::ColorHelper::FromArgb(255, 75, 75, 80);
    dropShadow->BlurRadius = 15.0f;
    dropShadow->Offset = Windows::Foundation::Numerics::float3(2.5f, 2.5f, 0.0f);
    // Associate the shape of the shadow with the shape of the target element
    dropShadow->Mask = shadowTarget->GetAlphaMask();

    // Create a Visual to hold the shadow
    auto shadowVisual = compositor->CreateSpriteVisual();
    shadowVisual->Shadow = dropShadow;

    // Add the shadow as a child of the host in the visual tree
    Windows::UI::Xaml::Hosting::ElementCompositionPreview::SetElementChildVisual(shadowHost, shadowVisual);

    // Make sure size of shadow host and shadow visual always stay in sync
    auto bindSizeAnimation = compositor->CreateExpressionAnimation("hostVisual.Size");
    bindSizeAnimation->SetReferenceParameter("hostVisual", hostVisual);

    shadowVisual->StartAnimation("Size", bindSizeAnimation);
}

Verre givréFrosted glass

Créez un effet qui estompe et teint le contenu en arrière-plan.Create an effect that blurs and tints background content. Notez que les développeurs doivent installer le package NuGet Win2D pour utiliser des effets.Note that developers need to install the Win2D NuGet package to use effects. Consultez la page d’accueil Win2D pour obtenir les instructions d’installation.See the Win2D homepage for installation instructions.

Vue d’ensemble de l’implémentationImplementation overview

  1. Obtenir le visuel de document pour l’élément hôteGet handout Visual for the host element
  2. Créer une arborescence d’effet de flou à l’aide de Win2D et CompositionEffectSourceParameterCreate a blur effect tree using Win2D and CompositionEffectSourceParameter
  3. Créer un élément CompositionEffectBrush en fonction de l’arborescence d’effetCreate a CompositionEffectBrush based on the effect tree
  4. Définir l’entrée de l’élément CompositionEffectBrush sur CompositionBackdropBrush, ce qui permet d’appliquer un effet au contenu se trouvant derrière un élément SpriteVisualSet input of the CompositionEffectBrush to a CompositionBackdropBrush, which allows an effect to be applied to the content behind a SpriteVisual
  5. Définissez CompositionEffectBrush comme contenu d’un nouveau SpriteVisual, puis définissez SpriteVisual comme enfant de l’élément hôte.Set the CompositionEffectBrush as the content of a new SpriteVisual, and set the SpriteVisual as the child of the host element. Vous pouvez également utiliser un XamlCompositionBrushBase.You could alternative use a XamlCompositionBrushBase.
  6. Lier la taille de l’élément SpriteVisual à la taille de l’hôte en utilisant une ExpressionAnimationBind size of the SpriteVisual to the size of the host using an ExpressionAnimation
<Grid Width="300" Height="300" Grid.Column="1">
    <Image
        Source="Assets/Images/2.jpg"
        Width="200"
        Height="200" />
    <Canvas
        x:Name="GlassHost"
        Width="150"
        Height="300"
        HorizontalAlignment="Right" />
</Grid>
public MainPage()
{
    InitializeComponent();
    InitializeFrostedGlass(GlassHost);
}

private void InitializeFrostedGlass(UIElement glassHost)
{
    Visual hostVisual = ElementCompositionPreview.GetElementVisual(glassHost);
    Compositor compositor = hostVisual.Compositor;

    // Create a glass effect, requires Win2D NuGet package
    var glassEffect = new GaussianBlurEffect
    { 
        BlurAmount = 15.0f,
        BorderMode = EffectBorderMode.Hard,
        Source = new ArithmeticCompositeEffect
        {
            MultiplyAmount = 0,
            Source1Amount = 0.5f,
            Source2Amount = 0.5f,
            Source1 = new CompositionEffectSourceParameter("backdropBrush"),
            Source2 = new ColorSourceEffect
            {
                Color = Color.FromArgb(255, 245, 245, 245)
            }
        }
    };

    //  Create an instance of the effect and set its source to a CompositionBackdropBrush
    var effectFactory = compositor.CreateEffectFactory(glassEffect);
    var backdropBrush = compositor.CreateBackdropBrush();
    var effectBrush = effectFactory.CreateBrush();

    effectBrush.SetSourceParameter("backdropBrush", backdropBrush);

    // Create a Visual to contain the frosted glass effect
    var glassVisual = compositor.CreateSpriteVisual();
    glassVisual.Brush = effectBrush;

    // Add the blur as a child of the host in the visual tree
    ElementCompositionPreview.SetElementChildVisual(glassHost, glassVisual);

    // Make sure size of glass host and glass visual always stay in sync
    var bindSizeAnimation = compositor.CreateExpressionAnimation("hostVisual.Size");
    bindSizeAnimation.SetReferenceParameter("hostVisual", hostVisual);

    glassVisual.StartAnimation("Size", bindSizeAnimation);
}

Ressources supplémentairesAdditional Resources