Utilizzo del livello visivo con XAMLUsing the Visual Layer with XAML

La maggior parte delle app che usano le funzionalità del livello visivo impiega il linguaggio XAML per definire il contenuto principale dell'interfaccia utente.Most apps that consume Visual Layer capabilities will use XAML to define the main UI content. Nell'aggiornamento dell'anniversario di Windows 10 sono disponibili nuove funzionalità nel framework XAML e nel livello visivo che consentono di combinare più facilmente queste due tecnologie per creare straordinarie esperienze utente.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. La funzionalità di interoperabilità di XAML e Visual Layer può essere usata per creare animazioni e effetti avanzati non disponibili usando solo le API XAML.XAML and Visual Layer interop functionality can be used to create advanced animations and effects not available using XAML APIs alone. ad esempio:This includes:

  • Effetti pennello, ad esempio sfocatura e vetro ghiacciatoBrush effects like blur and frosted glass
  • Effetti di illuminazione dinamicaDynamic lighting effects
  • Parallassi e animazioni a scorrimentoScroll driven animations and parallax
  • Animazioni del layout automaticoAutomatic layout animations
  • Pixel-ombreggiatura perfettaPixel-perfect drop shadows

Questi effetti e animazioni possono essere applicati al contenuto XAML esistente, quindi non è necessario ristrutturare in modo significativo l'app XAML per sfruttare le nuove funzionalità.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. Animazioni del layout, ombreggiature ed effetti di sfumatura sono illustrati nella sezione Ricette riportata più avanti.Layout animations, shadows, and blur effects are covered in the Recipes section below. Per un esempio di codice che implementa l'effetto parallasse, vedi l'esempio ParallaxingListItems.For a code sample implementing parallax, see the ParallaxingListItems sample. Molti esempi di implementazione di animazioni, ombreggiature ed effetti sono disponibili anche nel repository WindowsUIDevLabs.The WindowsUIDevLabs repository also has several other samples for implementing animations, shadows and effects.

Classe XamlCompositionBrushBaseThe XamlCompositionBrushBase class

XamlCompositionBrush fornisce una classe base per i pennelli XAML che disegnano un'area con una CompositionBrush.XamlCompositionBrush provides a base class for XAML brushes that paint an area with a CompositionBrush. Questa operazione può essere usata per applicare facilmente effetti di composizione come sfocatura o Glass a elementi dell'interfaccia utente XAML.This can be used to easily apply composition effects like blur or frosted glass to XAML UI elements.

Per altre informazioni sull'uso dei pennelli con l'interfaccia utente XAML, vedere la sezione pennelli .See the Brushes section for more info on using brushes with XAML UI.

Per esempi di codice, vedi la pagina di riferimento per XamlCompositionBrushBase.For code examples, see the reference page for XamlCompositionBrushBase.

Classe XamlLightThe XamlLight class

XamlLight fornisce una classe base per gli effetti di illuminazione XAML che illuminano dinamicamente un'area con una CompositionLight.XamlLight provides a base class for XAML lighting effects that dynamically light an area with a CompositionLight.

Vedere la sezione illuminazione per altre informazioni sull'uso delle luci, inclusa l'illuminazione degli elementi dell'interfaccia utente XAML.See the Lighting section for more info on using lights, including lighting XAML UI elements.

Per esempi di codice, vedere la pagina di riferimento per XamlLight.For code examples, see the reference page for XamlLight.

La classe ElementCompositionPreviewThe ElementCompositionPreview class

ElementCompositionPreview è una classe statica che fornisce la funzionalità di interoperabilità di XAML e Visual Layer.ElementCompositionPreview is a static class that provides XAML and Visual Layer interop functionality. Per una panoramica del livello visivo e delle relative funzionalità, vedi Livello visivo.For an overview of the Visual Layer and its functionality, see Visual Layer. La classe ElementCompositionPreview fornisce i metodi seguenti:The ElementCompositionPreview class provides the following methods:

  • GetElementVisual: ottiene un oggetto visivo "dispensa" usato per eseguire il rendering di questo elementoGetElementVisual: Get a "handout" Visual that is used to render this element
  • SetElementChildVisual: imposta un oggetto visivo "handin" come ultimo figlio della struttura ad albero visuale di questo elemento.SetElementChildVisual: Sets a "handin" Visual as the last child of this element’s visual tree. Questo oggetto visivo verrà posizionato sopra il resto dell'elemento.This Visual will draw on top of the rest of the element.
  • GetElementChildVisual: recupera il set visivo usando SetElementChildVisualGetElementChildVisual: Retrieve the Visual set using SetElementChildVisual
  • GetScrollViewerManipulationPropertySet: ottiene un oggetto che può essere usato per creare animazioni a 60 fps basate sull'offset di scorrimento in un elemento ScrollViewerGetScrollViewerManipulationPropertySet: Get an object that can be used to create 60fps animations based on scroll offset in a ScrollViewer

Considerazioni su ElementCompositionPreview.GetElementVisualRemarks on ElementCompositionPreview.GetElementVisual

ElementCompositionPreview.GetElementVisual restituisce un oggetto visivo "ricevuto" usato per eseguire il rendering di UIElement.ElementCompositionPreview.GetElementVisual returns a “handout” Visual that is used to render the given UIElement. Proprietà come Visual.Opacity, Visual.Offset, e Visual.Size vengono impostate dal framework XAML in base allo stato dell'oggetto UIElement.Properties such as Visual.Opacity, Visual.Offset, and Visual.Size are set by the XAML framework based on the state of the UIElement. In questo modo possono essere abilitate tecniche specifiche come le animazioni di riposizionamento implicite (vedi Ricette).This enables techniques such as implicit reposition animations (see Recipes).

Poiché le proprietà Offset e Size vengono impostate in funzione del layout del framework XAML, gli sviluppatori devono prestare molta attenzione quando applicano modifiche o animazioni a queste proprietà.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. È opportuno applicare modifiche o animazioni alla proprietà Offset solo se l'angolo superiore sinistro dell'elemento ha la stessa posizione del relativo elemento padre nel layout.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. In genere, non è consigliabile modificare la dimensione ma l'accesso a questa proprietà può comunque risultare molto utile.Size should generally not be modified, but accessing the property may be useful. Gli esempi di ombreggiature e vetro sfumato riportati di seguito, ad esempio, usano la proprietà Dimensione di un oggetto visivo ricevuto come input di un'animazione.For example, the Drop Shadow and Frosted Glass samples below use Size of a handout Visual as input to an animation.

Come precisazione aggiuntiva, occorre sottolineare che le proprietà aggiornate dell'oggetto visivo ricevuto non vengono riflesse nell'oggetto UIElement corrispondente.As an additional caveat, updated properties of the handout Visual will not be reflected in the corresponding UIElement. Ad esempio, se si imposta UIElement.Opacity su 0,5, l'opacità dell'oggetto visivo corrispondente verrà impostata su 0,5.So for example, setting UIElement.Opacity to 0.5 will set the corresponding handout Visual’s Opacity to 0.5. Se invece si imposta la proprietà Opacità dell'oggetto visivo ricevuto su 0,5, il contenuto verrà effettivamente visualizzato con un'opacità del 50%, ma il valore della proprietà Opacità dell'oggetto UIElement corrispondente non verrà modificato.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.

Esempio di animazione OffsetExample of Offset animation

Risposta errata.Incorrect

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

Risposta esatta.Correct

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

Il metodo ElementCompositionPreview.SetElementChildVisualThe ElementCompositionPreview.SetElementChildVisual method

ElementCompositionPreview.SetElementChildVisual consente allo sviluppatore di fornire un oggetto visivo "inviato", che verrà visualizzato nell'ambito della struttura ad albero visuale di un elemento.ElementCompositionPreview.SetElementChildVisual allows the developer to supply a “handin” Visual that will appear as part of an element’s Visual Tree. Gli sviluppatori, in questo modo, possono creare una "Composition Island" in cui all'interno di un'interfaccia utente XAML siano visualizzati contenuti basati su oggetti visivi.This allows developers to create a “Composition Island” where Visual-based content can appear inside a XAML UI. Gli sviluppatori devono essere molto prudenti nell'utilizzo di questa tecnica poiché i contenuti basati su oggetti visivi non garantiscono la stessa accessibilità e la stessa esperienza utente dei contenuti 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. Pertanto, è consigliabile usare questa tecnica solo quando è necessario implementare effetti personalizzati, ad esempio quelli descritti nella sezione Ricette seguente.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.

Metodi GetAlphaMaskGetAlphaMask methods

Le classi Image, TextBlock e Shape implementano ognuna un metodo denominato GetAlphaMask, che restituisce una classe CompositionBrush, la quale rappresenta un'immagine in gradazioni di grigio con la forma dell'elemento.Image, TextBlock, and Shape each implement a method called GetAlphaMask that returns a CompositionBrush representing a grayscale image with the shape of the element. La classe CompositionBrush può essere usata come input per la proprietà DropShadow di una composizione, in modo che l'ombreggiatura possa riflettere la forma dell'elemento, anziché un rettangolo.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. Questo garantisce anche ombreggiature realmente basate sui contorni, perfette a livello di pixel, per elementi di testo, immagini con lettere e forme.This enables pixel perfect, contour-based shadows for text, images with alpha, and shapes. Per un esempio di questa API, vedi la sezione Ombreggiatura riportata di seguito.See Drop Shadow below for an example of this API.

RecipeRecipes

Animazione di riposizionamentoReposition animation

Con le animazioni di composizione implicite, uno sviluppatore può automaticamente animare le modifiche nel layout di un elemento inerenti al relativo elemento padre.Using Composition Implicit Animations, a developer can automatically animate changes in an element’s layout relative to its parent. Modificando il Margine del pulsante seguente, ad esempio, il pulsante si animerà automaticamente nella nuova posizione nel layout.For example, if you change the Margin of the button below, it will automatically animate to its new layout position.

Panoramica dell'implementazioneImplementation overview

  1. Ottieni l'oggetto visivo ricevuto per l'elemento di destinazioneGet the handout Visual for the target element
  2. Crea una classe ImplicitAnimationCollection che animi automaticamente le modifiche nella proprietà OffsetCreate an ImplicitAnimationCollection that automatically animates changes in the Offset property
  3. Associa la classe ImplicitAnimationCollection all'oggetto visivo di supportoAssociate 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;
}

OmbreggiaturaDrop shadow

Applica un'ombreggiatura perfetta a livello di pixel a un oggetto UIElement, ad esempio un ellisse contenente un'immagine.Apply a pixel-perfect drop shadow to a UIElement, for example an Ellipse containing a picture. Poiché l'ombreggiatura richiede un SpriteVisual creato dall'app, dobbiamo creare un elemento "host" che contenga lo SpriteVisual tramite 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.

Panoramica dell'implementazioneImplementation overview

  1. Ottieni l'oggetto visivo ricevuto per l'elemento hostGet the handout Visual for the host element
  2. Crea un DropShadow Windows.UI.CompositionCreate a Windows.UI.Composition DropShadow
  3. Configura il DropShadow per ottenerne la forma dall'elemento di destinazione tramite una mascheraConfigure the DropShadow to get its shape from the target element via a mask
    • DropShadow è rettangolare per impostazione predefinita, pertanto non è necessario se la destinazione è rettangolareDropShadow is rectangular by default, so this is not necessary if the target is rectangular
  4. Associa l'ombreggiatura a un nuovo SpriteVisual e imposta lo SpriteVisual come figlio dell'elemento hostAttach shadow to a new SpriteVisual, and set the SpriteVisual as the child of the host element
  5. Associa le dimensioni dello SpriteVisual alle dimensioni dell'elemento host tramite una 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);
}

Nei due elenchi seguenti vengono illustrati gli equivalenti c++/WinRT e c++/CX del precedente codice C# usando la stessa struttura 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);
}

Vetro ghiacciatoFrosted glass

È possibile creare effetti di tinta e sfumatura sui contenuti in background.Create an effect that blurs and tints background content. Per usare questi effetti gli sviluppatori devono installare il pacchetto NuGet Win2D.Note that developers need to install the Win2D NuGet package to use effects. Vedi la home page di Win2D per istruzioni sull'installazione.See the Win2D homepage for installation instructions.

Panoramica dell'implementazioneImplementation overview

  1. Ottieni l'oggetto visivo ricevuto per l'elemento hostGet handout Visual for the host element
  2. Crea una struttura ad albero dell'effetto di sfumatura usando Win2D e CompositionEffectSourceParameterCreate a blur effect tree using Win2D and CompositionEffectSourceParameter
  3. Crea un pennello CompositionEffectBrush basato sulla struttura ad albero dell'effettoCreate a CompositionEffectBrush based on the effect tree
  4. Imposta l'input di CompositionEffectBrush su un pennello CompositionBackdropBrush, che consente l'applicazione dell'effetto ai contenuti presenti dietro uno SpriteVisualSet input of the CompositionEffectBrush to a CompositionBackdropBrush, which allows an effect to be applied to the content behind a SpriteVisual
  5. Impostare CompositionEffectBrush come contenuto di un nuovo SpriteVisuale impostare SpriteVisual come figlio dell'elemento host.Set the CompositionEffectBrush as the content of a new SpriteVisual, and set the SpriteVisual as the child of the host element. È possibile usare un'alternativa XamlCompositionBrushBase.You could alternative use a XamlCompositionBrushBase.
  6. Associa le dimensioni dello SpriteVisual alle dimensioni dell'elemento host tramite una 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);
}

Risorse aggiuntiveAdditional Resources