Xaml​Light Xaml​Light Xaml​Light Class

Definition

Provides a base class used to create XAML lights that use a CompositionLight to apply lighting effects to XAML elements and brushes.

public : class XamlLight : DependencyObject, IXamlLight, IXamlLightOverrides, IXamlLightProtectedpublic class XamlLight : DependencyObject, IXamlLight, IXamlLightOverrides, IXamlLightProtectedPublic Class XamlLight Inherits DependencyObject Implements IXamlLight, IXamlLightOverrides, IXamlLightProtected
Inheritance
Attributes
Windows 10 requirements
Device family
Windows 10 Creators Update (introduced v10.0.15063.0)
API contract
Windows.Foundation.UniversalApiContract (introduced v4)

Inherited Members

Inherited methods

Inherited properties

Examples

This example shows the definition for a custom XamlLight that applies a multicolored spotlight to targeted UIElements and Brushes:

public sealed class OrangeSpotLight : XamlLight
{
    // Register an attached property that enables apps to set a UIElement or Brush as a target for this light type in markup.
    public static readonly DependencyProperty IsTargetProperty =
        DependencyProperty.RegisterAttached(
        "IsTarget",
        typeof(bool),
        typeof(OrangeSpotLight),
        new PropertyMetadata(null, OnIsTargetChanged)
    );
    public static void SetIsTarget(DependencyObject target, bool value)
    {
        target.SetValue(IsTargetProperty, value);
    }
    public static Boolean GetIsTarget(DependencyObject target)
    {
        return (bool)target.GetValue(IsTargetProperty);
    }

    // Handle attached property changed to automatically target and untarget UIElements and Brushes.
    private static void OnIsTargetChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        var isAdding = (bool)e.NewValue;

        if (isAdding)
        {
            if (obj is UIElement)
            {
                XamlLight.AddTargetElement(GetIdStatic(), obj as UIElement);
            }
            else if (obj is Brush)
            {
                XamlLight.AddTargetBrush(GetIdStatic(), obj as Brush);
            }
        }
        else
        {
            if (obj is UIElement)
            {
                XamlLight.RemoveTargetElement(GetIdStatic(), obj as UIElement);
            }
            else if (obj is Brush)
            {
                XamlLight.RemoveTargetBrush(GetIdStatic(), obj as Brush);
            }
        }
    }

    protected override void OnConnected(UIElement newElement)
    {
        if (CompositionLight == null)
        {
            // OnConnected is called when the first target UIElement is shown on the screen. This enables delaying composition object creation until it's actually necessary.
            var spotLight = Window.Current.Compositor.CreateSpotLight();
            spotLight.InnerConeColor = Colors.Orange;
            spotLight.OuterConeColor = Colors.Yellow;
            spotLight.InnerConeAngleInDegrees = 30;
            spotLight.OuterConeAngleInDegrees = 45;
            spotLight.Offset = new System.Numerics.Vector3(30, 30, 200);
            CompositionLight = spotLight;
        }
    }

    protected override void OnDisconnected(UIElement oldElement)
    {
        // OnDisconnected is called when there are no more target UIElements on the screen. The CompositionLight should be disposed when no longer required.
        if (CompositionLight != null)
        {
            CompositionLight.Dispose();
            CompositionLight = null;
        }
    }

    protected override string GetId()
    {
        return GetIdStatic();
    }

    private static string GetIdStatic()
    {
        // This specifies the unique name of the light. In most cases you should use the type's FullName.
        return typeof(OrangeSpotLight).FullName;
    }
}
Public NotInheritable Class OrangeSpotLight
    Inherits XamlLight

    ' Register an attached property that enables apps to set a UIElement Or Brush as a target for this light type in markup.
    Public Shared ReadOnly IsTargetProperty As DependencyProperty = DependencyProperty.RegisterAttached(
            "IsTarget",
            GetType(Boolean),
            GetType(OrangeSpotLight),
            New PropertyMetadata(Nothing, New PropertyChangedCallback(AddressOf OnIsTargetChanged)
            )
        )

    Public Shared Sub SetIsTarget(target As DependencyObject, value As Boolean)
        target.SetValue(IsTargetProperty, value)
    End Sub

    Public Shared Function GetIsTarget(target As DependencyObject) As Boolean
        Return DirectCast(target.GetValue(IsTargetProperty), Boolean)
    End Function

    ' Handle attached property changed to automatically target And untarget UIElements And Brushes.
    Public Shared Sub OnIsTargetChanged(obj As DependencyObject, e As DependencyPropertyChangedEventArgs)
        Dim isAdding = DirectCast(e.NewValue, Boolean)

        If isAdding Then
            If TypeOf obj Is UIElement Then
                XamlLight.AddTargetElement(GetIdStatic(), TryCast(obj, UIElement))
            ElseIf TypeOf obj Is Brush Then
                XamlLight.AddTargetBrush(GetIdStatic(), TryCast(obj, Brush))
            End If
        Else
            If TypeOf obj Is UIElement Then
                XamlLight.RemoveTargetElement(GetIdStatic(), TryCast(obj, UIElement))
            ElseIf TypeOf obj Is Brush Then
                XamlLight.RemoveTargetBrush(GetIdStatic(), TryCast(obj, Brush))
            End If
        End If
    End Sub

    Protected Overrides Sub OnConnected(newElement As UIElement)
        If CompositionLight Is Nothing Then
            ' OnConnected Is called when the first target UIElement Is shown on the screen. This enables delaying composition object creation until it's actually necessary.
            Dim spotLight = Window.Current.Compositor.CreateSpotLight()
            spotLight.InnerConeColor = Colors.Orange
            spotLight.OuterConeColor = Colors.Yellow
            spotLight.InnerConeAngleInDegrees = 30
            spotLight.OuterConeAngleInDegrees = 45
            spotLight.Offset = New System.Numerics.Vector3(30, 30, 200)
            CompositionLight = spotLight
        End If
    End Sub

    Protected Overrides Sub OnDisconnected(oldElement As UIElement)
        ' OnDisconnected Is called when there are no more target UIElements on the screen. The CompositionLight should be disposed when no longer required.
        If CompositionLight IsNot Nothing Then
            CompositionLight.Dispose()
            CompositionLight = Nothing
        End If
    End Sub

    Protected Overrides Function GetId() As String
        Return GetIdStatic()
    End Function

    Private Shared Function GetIdStatic() As String
        ' This specifies the unique name of the light. In most cases you should use the type's FullName.
        Return GetType(OrangeSpotLight).FullName
    End Function
End Class
// OrangeSpotLight.h:
public ref class OrangeSpotLight sealed :
    public Windows::UI::Xaml::Media::XamlLight
{
public:
    OrangeSpotLight();

    static property Windows::UI::Xaml::DependencyProperty^ IsTargetProperty
    {
        Windows::UI::Xaml::DependencyProperty^ get() { return m_isTargetProperty; }
    };
    static void SetIsTarget(Windows::UI::Xaml::DependencyObject^ target, bool value);
    static bool GetIsTarget(Windows::UI::Xaml::DependencyObject^ target);

protected:
    virtual void OnConnected(Windows::UI::Xaml::UIElement^ newElement) override;
    virtual void OnDisconnected(Windows::UI::Xaml::UIElement^ oldElement) override;
    virtual Platform::String^ GetId() override;

private:
    static Windows::UI::Xaml::DependencyProperty^ m_isTargetProperty;
    static void OnIsTargetChanged(Windows::UI::Xaml::DependencyObject^ obj, Windows::UI::Xaml::DependencyPropertyChangedEventArgs^ e);

    inline static Platform::String^ GetIdStatic()
    {
        // This specifies the unique name of the light. In most cases you should use the type's FullName.
        return OrangeSpotLight::typeid->FullName;
    }
};

//OrangeSpotLight.cpp:

// Register an attached property that enables apps to set a UIElement or Brush as a target for this light type in markup.
DependencyProperty^ OrangeSpotLight::m_isTargetProperty = DependencyProperty::RegisterAttached(
    "IsTarget",
    bool::typeid,
    OrangeSpotLight::typeid,
    ref new PropertyMetadata(0.0, ref new PropertyChangedCallback(OnIsTargetChanged))
);

OrangeSpotLight::OrangeSpotLight()
{
}

void OrangeSpotLight::SetIsTarget(DependencyObject^ target, bool value)
{
    target->SetValue(IsTargetProperty, value);
}

bool OrangeSpotLight::GetIsTarget(DependencyObject^ target)
{
    return static_cast<bool>(target->GetValue(IsTargetProperty));
}

void OrangeSpotLight::OnIsTargetChanged(DependencyObject^ obj, DependencyPropertyChangedEventArgs^ e)
{
    auto isAdding = static_cast<bool>(e->NewValue);

    if (isAdding)
    {
        if (dynamic_cast<UIElement^>(obj))
        {
            XamlLight::AddTargetElement(GetIdStatic(), static_cast<UIElement^>(obj));
        }
        else if (dynamic_cast<Brush^>(obj))
        {
            XamlLight::AddTargetBrush(GetIdStatic(), static_cast<Brush^>(obj));
        }
    }
    else
    {
        if (dynamic_cast<UIElement^>(obj))
        {
            XamlLight::RemoveTargetElement(GetIdStatic(), static_cast<UIElement^>(obj));
        }
        else if (dynamic_cast<Brush^>(obj))
        {
            XamlLight::RemoveTargetBrush(GetIdStatic(), static_cast<Brush^>(obj));
        }
    }
}
void OrangeSpotLight::OnConnected(UIElement^ newElement)
{
    if (CompositionLight == nullptr)
    {
        // OnConnected is called when the first target UIElement is shown on the screen. This enables delaying composition object creation until it's actually necessary.
        auto spotLight = Window::Current->Compositor->CreateSpotLight();
        spotLight->InnerConeColor = Colors::Orange;
        spotLight->OuterConeColor = Colors::Yellow;
        spotLight->InnerConeAngleInDegrees = 30;
        spotLight->OuterConeAngleInDegrees = 45;
        spotLight->Offset = float3(30, 30, 200);

        CompositionLight = spotLight;
    }
}

void OrangeSpotLight::OnDisconnected(UIElement^ oldElement)
{
    // OnDisconnected is called when there are no more target UIElements on the screen. The CompositionLight should be disposed when no longer required.
    if (CompositionLight != nullptr)
    {
        delete CompositionLight;
        CompositionLight = nullptr;
    }
}

Platform::String^ OrangeSpotLight::GetId()
{
    return GetIdStatic();
}

The above light can then be applied to any XAML UIElement or Brush to light them. This example shows different potential usages:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid.Lights>
        <!-- Attach a light, similar to setting a CompositionLight's CoordinateSpace property -->
        <local:OrangeSpotLight />
    </Grid.Lights>

    <StackPanel>
        <!-- this border will be lit by a OrangeSpotLight, but not its children -->
        <Border BorderThickness="5">
            <Border.BorderBrush>
                <SolidColorBrush Color="White" local:OrangeSpotLight.IsTarget="true" />
            </Border.BorderBrush>
            <TextBlock Text="hello world" />
        </Border>

        <!-- this border and its content will be lit by OrangeSpotLight -->
        <Border BorderThickness="5" BorderBrush="White" Background="White" local:OrangeSpotLight.IsTarget="true">
            <TextBlock Text="hello world" Foreground="Gray" />
        </Border>

        <!-- this border will not be lit -->
        <Border BorderThickness="5">
            <Border.BorderBrush>
                <SolidColorBrush Color="Green" />
            </Border.BorderBrush>
            <TextBlock Text="hello world" />
        </Border>
    </StackPanel>
</Grid>
Important

Setting UIElement.Lights in markup as shown in the above example is only supported for apps with a Minimum Version equal to the Windows 10 Creators Update or later. For apps that target earlier minimum versions, lights must be created in code-behind.

Remarks

You can use XamlLight to create custom lights.

For example, it can be used to create a light that applies a composition SpotLight to target elements to light them.

XamlLight provides methods for targeting UIElements or XAML Brushes, applying lights to trees of UIElements, and helping manage the lifetime of CompositionLight resources based on whether they're currently in use.

Custom XamlLights can be used in conjunction with custom Brushes derived from XamlCompositionBrushBase which use a SceneLightingEffect to controls the reflective properties of elements when being lit by a XamlLight.

Targeting objects

If you target a Brush with a XamlLight then the portions of any UIElements using that Brush will be lit by the light.

If you target a UIElement with a XamlLight then the entire UIElement and its child UIElements will all be lit by the light.

Targets can be added and removed by calling methods on a XamlLight instance. XamlLights can also define custom attached properties to add and remove targets from markup.

Managing resources

When creating a XamlLight, it's usually a good practice to delay creating a CompositionLight and any related resources until the light is being used. The OnConnected method is called when a XamlLight is first used to target an element or brush on screen, so you can override OnConnected to safely create resources only when they're needed.

It's also a good practice to dispose of composition resources when they're no longer in use. The OnDisconnected method is called when a XamlLight instance is no longer in use anywhere on the screen, so you can override OnDisconnected to safely dispose of resources. If the XamlLight is later used again after being disconnected then OnConnected will be called again.

Constructors

XamlLight() XamlLight() XamlLight()

Initializes a new instance of the XamlLight class.

public : XamlLight()public XamlLight()Public Sub New()
Attributes

Properties

CompositionLight CompositionLight CompositionLight

Gets or sets the CompositionLight instance used to apply lighting effects.

protected : CompositionLight CompositionLight { get; set; }protected CompositionLight CompositionLight { get; set; }Protected ReadWrite Property CompositionLight As CompositionLight
Value
CompositionLight CompositionLight CompositionLight

An instance of a CompositionLight derived class used to apply lighting effects.

Attributes

Remarks

It's usually a good practice to manage the lifetime of the CompositionLight object by delaying its creation until needed and disposing of it when no longer in use.

Methods

AddTargetBrush(String, Brush) AddTargetBrush(String, Brush) AddTargetBrush(String, Brush)

Sets a Brush as a target of a XamlLight.

public : static void AddTargetBrush(PlatForm::String lightId, Brush brush)public static void AddTargetBrush(String lightId, Brush brush)Public Static Function AddTargetBrush(lightId As String, brush As Brush) As void
Parameters
lightId
PlatForm::String String String

The identifier for the XamlLight that should target the Brush.

brush
Brush Brush Brush

The Brush that the light should target.

Attributes

AddTargetElement(String, UIElement) AddTargetElement(String, UIElement) AddTargetElement(String, UIElement)

Sets a UIElement as a target of a XamlLight.

public : static void AddTargetElement(PlatForm::String lightId, UIElement element)public static void AddTargetElement(String lightId, UIElement element)Public Static Function AddTargetElement(lightId As String, element As UIElement) As void
Parameters
lightId
PlatForm::String String String

The identifier for the XamlLight that should target the UIElement.

element
UIElement UIElement UIElement

The UIElement that the light should target.

Attributes

GetId() GetId() GetId()

Returns the identifier for the custom XamlLight type.

In most cases you should use a unique identifier to prevent conflicts. For example, you can use the FullName of your custom XamlLight type.

The identifier is used to add and remove Brushes and UIElements as targets for a specific light type.

protected : virtual PlatForm::String GetId()protected virtual string GetId()Protected Overridable Function GetId() As string
Returns
PlatForm::String string string

The identifier for the XamlLight.

Attributes

OnConnected(UIElement) OnConnected(UIElement) OnConnected(UIElement)

This method is automatically called when the XamlLight is first in use on the screen, or after being previously disconnected then used again.

This provides an opportunity to create resources such as the CompositionLight only when required.

OnDisconnected will be called when the XamlLight is no longer being used to light any UIElements or Brushes.

protected : virtual void OnConnected(UIElement newElement)protected virtual void OnConnected(UIElement newElement)Protected Overridable Function OnConnected(newElement As UIElement) As void
Parameters
newElement
UIElement UIElement UIElement

The UIElement that the light is attached to.

Attributes

OnDisconnected(UIElement) OnDisconnected(UIElement) OnDisconnected(UIElement)

This method is automatically called when the XamlLight is no longer in use anywhere on the screen.

This provides an opportunity to safely dispose of resources such as the CompositionLight when they aren't currently required.

OnConnected will be called again if the XamlLight is later used to light any UIElements or Brushes after being disconnected.

protected : virtual void OnDisconnected(UIElement oldElement)protected virtual void OnDisconnected(UIElement oldElement)Protected Overridable Function OnDisconnected(oldElement As UIElement) As void
Parameters
oldElement
UIElement UIElement UIElement

The UIElement that the light is attached to.

Attributes

RemoveTargetBrush(String, Brush) RemoveTargetBrush(String, Brush) RemoveTargetBrush(String, Brush)

Stops a Brush from being a target of a XamlLight.

public : static void RemoveTargetBrush(PlatForm::String lightId, Brush brush)public static void RemoveTargetBrush(String lightId, Brush brush)Public Static Function RemoveTargetBrush(lightId As String, brush As Brush) As void
Parameters
lightId
PlatForm::String String String

The identifier for the XamlLight that should no longer target the Brush.

brush
Brush Brush Brush

The Brush that the light should no longer target.

Attributes

RemoveTargetElement(String, UIElement) RemoveTargetElement(String, UIElement) RemoveTargetElement(String, UIElement)

Stops a UIElement from being a target of a XamlLight.

public : static void RemoveTargetElement(PlatForm::String lightId, UIElement element)public static void RemoveTargetElement(String lightId, UIElement element)Public Static Function RemoveTargetElement(lightId As String, element As UIElement) As void
Parameters
lightId
PlatForm::String String String

The identifier for the XamlLight that should no longer target the UIElement.

element
UIElement UIElement UIElement

The UIElement that the light should no longer target.

Attributes