Tag Archives: UI

How to Restart your App Programmatically

For some apps (especially games) it is not uncommon for the app to get into a state where it needs to restart – perhaps after a license update, after installing downloadable content, its caches have become corrupt or unwieldy, or for any other reason where the app needs to refresh state from scratch. In earlier releases, your only option would have been to prompt the user to close and relaunch, or to call CoreApplication.Exit – and both options provide sub-optimal user experience.

We have therefore introduced a new API that enables an app to request immediate termination and restart, and to pass arbitrary arguments into the fresh instance. In this post, we’ll look at how this works and how you can build it into your app. This is available now in Insider builds from Build 16226 onwards, along with the corresponding SDK.

Here’s a sample app, called TestRestart. 

The app provides a ListView of cities on the left, the currently-selected city on the right and a TextBox for providing arguments to the app when it is restarted. When the user taps the Request Restart button, the app will terminate and restart itself, passing in the supplied arguments. The new API, RequestRestartAsync, is exposed as a static method on the CoreApplication object. It takes a string parameter, which can be any string value you like – including input from the user or another external entity. If you do choose to accept input in this way, it is your responsibility to validate it correctly to make sure it conforms to whatever constraints you choose to impose. You should do this validation on input, before passing it to RequestRestartAsync. In this sample app, we’re expecting the user to type in the name of a city.


async private void DoRestartRequest()
{
    bool isValidPayload = false;
    string payload = restartArgs.Text;
    if (!string.IsNullOrEmpty(payload))
    {
        foreach (ImageViewModel imageItem in imageListView.Items)
        {
            if (imageItem.Name == payload)
            {
                isValidPayload = true;
                break;
            }
        }
    }

    if (isValidPayload)
    {
        AppRestartFailureReason result =
            await CoreApplication.RequestRestartAsync(payload);
        if (result == AppRestartFailureReason.NotInForeground ||
            result == AppRestartFailureReason.RestartPending ||
            result == AppRestartFailureReason.Other)
        {
            Debug.WriteLine("RequestRestartAsync failed: {0}", result);
        }
    }
}

To mitigate privacy concerns, an app is only permitted to restart itself if it is in the foreground at the time it makes the request. When the app restarts, it restarts with normal UI – that is, as a normal foreground window. If we were to permit a background task or minimized app to restart, the result would be unexpected to the user. This is why the API is framed as a request. If the request is denied, the app would need to handle the failure – perhaps by waiting until it is in the foreground and trying again. If you were to request a restart and then through some twist of logic managed to request it again before the system started the operation, then you’d get the RestartPending result, although this is an edge case. You’re unlikely to ever get the other result – unless something goes wrong in the platform.

Note that this is the only significant constraint, but you should use this API carefully. For example, you probably should not use it if your app was not originally launched by the user – for example, if it was launched as the result of a share or picker operation. Restarting in the middle of one of those contract operations would certainly confuse the user.

If the request is granted, the app is terminated and then restarted. There are many different ways to activate an app: in addition to a regular launch activation, apps can choose to support file activation, protocol activation, share or picker activation and so on. The list is documented here. For the restart case, the app will be activated as a regular launch – just as if the user had closed the app manually and tapped its tile to launch it again – but including the arbitrary arguments supplied earlier (if any).

In your App class, you should handle this by overriding the OnActivated method. Test the ActivationKind, and if it’s ActivationKind.Launch, then the incoming IActivatedEventArgs will be a LaunchActivatedEventArgs. From this, you can get hold of the incoming activation arguments. For a regular user-initiated launch, the Arguments will be empty, so if it’s not empty you could simply infer that this is a restart activation. You can also check the PreviousExecutionState, which for a restart operation will be set to Terminated.

Although the arguments might have originated from an untrusted source (eg, the user), you should have done the validation before requesting restart. If so, you can consider them trustworthy when you receive them in OnActivated.


protected override void OnActivated(IActivatedEventArgs args)
{
    switch (args.Kind)
    {
        case ActivationKind.Launch:
            LaunchActivatedEventArgs launchArgs = args as LaunchActivatedEventArgs;
            string argString = launchArgs.Arguments;

            Frame rootFrame = Window.Current.Content as Frame;
            if (rootFrame == null)
            {
                rootFrame = new Frame();
                Window.Current.Content = rootFrame;
            }
            rootFrame.Navigate(typeof(MainPage), argString);
            Window.Current.Activate();
            break;
    }
}

What you do with the incoming arguments is entirely up to you. In this app, we’re simply passing them on to the MainPage. In the MainPage in turn, we have an override of OnNavigatedTo which uses the string to select an item in the ListView:


protected override void OnNavigatedTo(NavigationEventArgs e)

{
    string payload = e.Parameter as string;
    if (!string.IsNullOrEmpty(payload))
    {
        foreach (ImageViewModel imageItem in imageListView.Items)
        {
            if (imageItem.Name == payload)
            {
                imageListView.SelectedItem = imageItem;
                break;
            }
        }
    }
}

As you can see, the CoreApplication.RequestRestartAsync method is a simple API. You can use it to terminate your app immediately, and have it restart as if by user action, with the additional option of passing in arbitrary arguments on activation.

Sample Code here.

New Lights and PropertySet Interop – XAML and Visual Layer Interop, Part Two

In the last post, we explored using XamlCompositionBrushBase and LoadedImageSurface to create custom CompositionBrushes that can be used to paint XAML elements directly in your markup. In today’s post, we’ll continue our look into the new improvements made to the XAML and Visual Layer Interop APIs available in the Windows 10 Creators Update.

In this blog series, we’ll cover some of these improvements in the Creators Update and look at the following APIs:

  • In Part 1:
    • XamlCompositionBrushBase – easily paint a XAML UIElement with a CompositionBrush
    • LoadedImageSurface – load an image easily and use with Composition APIs
  • In Part 2, today’s post:
    • XamlLights – apply lights to your XAML UI with a single line of XAML
    • PointerPositionPropertySet – create 60 FPS animations using pointer position, off the UI thread!
    • Enabling the Translation property – animate a XAML UI Element using Composition animation

If you’d like to review the previously available ElementCompositionPreview APIs, for example working with “hand-in” and “hand-out” Visuals, you can quickly catch up here.

Lighting UI with XamlLights

A powerful new feature in the Creators Update is the ability to set and use a Lighting effect directly in XAML by leveraging the abstract XamlLight class.

Creating a XamlLight starts just like a XamlCompositionBrushBase does, with an OnConnected and OnDisconnected method (see Part One here), but this time you inherit from the XamlLight subclass to create your own unique lighting that can be used directly in XAML. Microsoft uses this with the Reveal effect that comes with the Creators Update.

To see this in action, let’s build a demo that creates the animated GIF you see at the top of this post. It combines everything you learned about XamlCompositionBrushBase and LoadedImageSurface in the last post, but this example has two XamlLights: a HoverLight and an AmbientLight.

Let’s begin with creating the AmbientLight first. To get started, we begin similarly to the XamlCompositionBrushBase with an OnConnected and OnDisconnected method. However, for a XamlLight we set the CompositionLight property of the XamlLight subclass.


public class AmbLight : XamlLight
{
    protected override void OnConnected(UIElement newElement)
    {
        Compositor compositor = Window.Current.Compositor;

        // Create AmbientLight and set its properties
        AmbientLight ambientLight = compositor.CreateAmbientLight();
        ambientLight.Color = Colors.White;

        // Associate CompositionLight with XamlLight
        CompositionLight = ambientLight;

        // Add UIElement to the Light's Targets
        AmbLight.AddTargetElement(GetId(), newElement);
    }

    protected override void OnDisconnected(UIElement oldElement)
    {
        // Dispose Light when it is removed from the tree
        AmbLight.RemoveTargetElement(GetId(), oldElement);
        CompositionLight.Dispose();
    }

    protected override string GetId() => typeof(AmbLight).FullName;
}

With ambient lighting done, let’s build the SpotLight XamlLight. One of the main things we want the SpotLight to do is follow the user’s pointer. To do this, we can now use GetPointerPositionPropertySet method of ElementCompositionPreview to get a CompositionPropertySet we can use with a Composition ExpressionAnimation (PointerPositionPropertySet is explained in more detail in the PropertySets section below).

Here is the finished XamlLight implementation that creates that animated spotlight. Read the code comments to see the main parts of the effects, particularly how the resting position and animated offset position are used to create the lighting.


public class HoverLight : XamlLight 
{
    private ExpressionAnimation _lightPositionExpression;
    private Vector3KeyFrameAnimation _offsetAnimation;

    protected override void OnConnected(UIElement targetElement)
    {
        Compositor compositor = Window.Current.Compositor;

        // Create SpotLight and set its properties
        SpotLight spotLight = compositor.CreateSpotLight();
        spotLight.InnerConeAngleInDegrees = 50f;
        spotLight.InnerConeColor = Colors.FloralWhite;
        spotLight.OuterConeAngleInDegrees = 0f;
        spotLight.ConstantAttenuation = 1f;
        spotLight.LinearAttenuation = 0.253f;
        spotLight.QuadraticAttenuation = 0.58f;

        // Associate CompositionLight with XamlLight
        this.CompositionLight = spotLight;

        // Define resting position Animation
        Vector3 restingPosition = new Vector3(200, 200, 400);
        CubicBezierEasingFunction cbEasing = compositor.CreateCubicBezierEasingFunction( new Vector2(0.3f, 0.7f), new Vector2(0.9f, 0.5f));
        _offsetAnimation = compositor.CreateVector3KeyFrameAnimation();
        _offsetAnimation.InsertKeyFrame(1, restingPosition, cbEasing);
        _offsetAnimation.Duration = TimeSpan.FromSeconds(0.5f);

        spotLight.Offset = restingPosition;

        // Define expression animation that relates light's offset to pointer position 
        CompositionPropertySet hoverPosition = ElementCompositionPreview.GetPointerPositionPropertySet(targetElement);
        _lightPositionExpression = compositor.CreateExpressionAnimation("Vector3(hover.Position.X, hover.Position.Y, height)");
        _lightPositionExpression.SetReferenceParameter("hover", hoverPosition);
        _lightPositionExpression.SetScalarParameter("height", 15.0f);

        // Configure pointer entered/ exited events
        targetElement.PointerMoved += TargetElement_PointerMoved;
        targetElement.PointerExited += TargetElement_PointerExited;

        // Add UIElement to the Light's Targets
        HoverLight.AddTargetElement(GetId(), targetElement);
    }

    private void MoveToRestingPosition()
    {
        // Start animation on SpotLight's Offset 
        CompositionLight?.StartAnimation("Offset", _offsetAnimation);
    }

    private void TargetElement_PointerMoved(object sender, PointerRoutedEventArgs e)
    {
        if (CompositionLight == null) return;

        // touch input is still UI thread-bound as of the Creators Update
        if (e.Pointer.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Touch)
        {
            Vector2 offset = e.GetCurrentPoint((UIElement)sender).Position.ToVector2();
            (CompositionLight as SpotLight).Offset = new Vector3(offset.X, offset.Y, 15);
        }
        else
        {
            // Get the pointer's current position from the property and bind the SpotLight's X-Y Offset
            CompositionLight.StartAnimation("Offset", _lightPositionExpression);
        }
    }

    private void TargetElement_PointerExited(object sender, PointerRoutedEventArgs e)
    {
        // Move to resting state when pointer leaves targeted UIElement
        MoveToRestingPosition();
    }

    protected override void OnDisconnected(UIElement oldElement)
    {
        // Dispose Light and Composition resources when it is removed from the tree
        HoverLight.RemoveTargetElement(GetId(), oldElement);
        CompositionLight.Dispose();
        _lightPositionExpression.Dispose();
        _offsetAnimation.Dispose();
    }

    protected override string GetId() => typeof(HoverLight).FullName;
}

Now, with the HoverLight class done, we can add both the AmbLight and the HoverLight to previous ImageEffectBrush (find ImageEffectBrush in the last post):


<Grid>
            <Grid.Background>
                <brushes:ImageEffectBrush ImageUriString="ms-appx:///Images/Background.png" />
            </Grid.Background>
 
            <Grid.Lights>
                <lights:HoverLight/>
                <lights:AmbLight/>
            </Grid.Lights>
</Grid>

Note: To add a XamlLight in markup, your Min SDK version must be set to Creators Update, otherwise you can set it in the code behind.

For more information, go here to read more about using XamlLight and here to see the Lighting documentation.

Using CompositionPropertySets

When you want to use the values of the ScrollViewer’s Offset or the Pointer’s X and Y position (e.g. mouse cursor) to do things like animate effects, you can use ElementCompositionPreview to retrieve their PropertySets. This allows you to create amazingly smooth, 60 FPS animations that are not tied to the UI thread. These methods let you get the values from user interaction for things like animations and lighting.

Using ScrollViewerManipulationPropertySet

This PropertySet is useful for animating things like Parallax, Translation and Opacity.


// Gets the manipulation <ScrollViewer x:Name="MyScrollViewer"/>
CompositionPropertySet scrollViewerManipulationPropertySet = 
    ElementCompositionPreview.GetScrollViewerManipulationPropertySet(MyScrollViewer);

To see an example, go to the Smooth Interaction and Motion blog post in this series. There is a section devoted to using the ScrollViewerManipulationPropertySet to drive the animation.

Using PointerPositionPropertySet (new!)

New in the Creators Update, is the PointerPositionPropertySet. This PropertySet is useful for creating animations for lighting and tilt. Like ScrollViewerManipulationPropertySet, PointerPositionPropertySet enables fast, smooth and UI thread independent animations.

A great example of this is the animation mechanism behind Fluent Design’s RevealBrush, where you see lighting effects on the edges on the UIElements. This effect is created by a CompositionLight, which has an Offset property animated by an ExpressionAnimation using the values obtained from the PointerPositionPropertySet.


// Useful for creating an ExpressionAnimation
CompositionPropertySet pointerPositionPropertySet = ElementCompositionPreview.GetPointerPositionPropertySet(targetElement);
ExpressionAnimation expressionAnimation = compositor.CreateExpressionAnimation("Vector3(param.Position.X, param.Position.Y, height)");
expressionAnimation.SetReferenceParameter("param", pointerPositionPropertySet);

To get a better understanding of how you can use this to power animations in your app, let’s explore XamlLights and create a demo that uses the PointerPositionPropertySet to animate a SpotLight.

Enabling Translation Property – Animating a XAML Element’s Offset using Composition Animations

As discussed in our previous blog post, property sharing between the Framework Layer and the Visual Layer used to be tricky prior to the Creators Update. The following Visual properties are shared between UIElements and their backing Visuals:

  • Offset
  • Scale
  • Opacity
  • TransformMatrix
  • InsetClip
  • CompositeMode

Prior to the Creators update, Scale and Offset were especially tricky because, as mentioned before, a UIElement isn’t aware of changes to the property values on the hand-out Visual, even though the hand-out Visual is aware of changes to the UIElement. Consequently, if you change the value of the hand-out Visual’s Offset or Size property and the UIElement’s position changes due to a page resize, the UIElement’s previous position values will stomp all over your hand-out Visual’s values.

Now with the Creators Update, this has become much easier to deal with as you can prevent Scale and Offset stomping by enabling the new Translation property on your element, by way of the ElementCompositionPreview object.


ElementCompositionPreview.SetIsTranslationEnabled(Rectangle1, true);

//Now initialize the value of Translation in the PropertySet to zero for first use to avoid timing issues. This ensures that the property is ready for use immediately.

var rect1VisualPropertySet = ElementCompositionPreview.GetElementVisual(Rectangle1).Properties;
rect1VisualPropertySet.InsertVector3("Translation", Vector3.Zero);

Then, animate the visual’s Translation property where previously you would have animated its Offset property.


// Old way, subject to property stomping:
visual.StartAnimation("Offset.Y", animation);
// New way, available in the Creators Update
visual.StartAnimation("Translation.Y", animation);

By animating a different property from the one affected during layout passes, you avoid any unwanted offset stomping coming from the XAML layer.

Wrapping up

In the past couple posts, we explored some of the new features of XAML and Composition Interop and how using Composition features in your XAML markup is easier than ever. From painting your UIElements with CompositionBrushes and applying lighting, to smooth off-UIThread animations, the power of the Composition API is more accessible than ever.

In the next post, we’ll dive deeper into how you can chain Composition effects to create amazing materials and help drive the evolution of Fluent Design.

Resources

Working with Brushes and Content – XAML and Visual Layer Interop, Part One

The Composition APIs empower Universal Windows Platform (UWP) developers to do beautiful and powerful things when they access the Visual Layer. In the Windows 10 Creators Update, we made working with the Visual Layer much easier with new, powerful APIs.

In this blog series, we’ll cover some of these improvements in the Creators Update and take a look at the following APIs:

  • In Part 1, today’s post:
    • XamlCompositionBrushBase – easily paint a XAML UIElement with a CompositionBrush
    • LoadedImageSurface – load an image easily and use with Composition APIs
  • In Part 2, we’ll look at:
    • XamlLights – apply lights to your XAML UI with a single line of XAML
    • PointerPositionPropertySet – create 60 FPS animations using pointer position, off the UI thread!
    • Enabling the Translation property – animate a XAML UI Element using Composition animation

If you’d like to review the previously available ElementCompositionPreview APIs, for example working with “hand-in” and “hand-out” Visuals, you can quickly catch up here.

Using XamlCompositionBrushBase

One of the benefits of the new Composition and XAML interop APIs is the ability to use a CompositionBrush to directly paint a XAML UIElement rather than being limited to XAML brushes only. For example, you can create a CompositionEffectBrush that applies a tinted blur to the content beneath and use the brush to paint a XAML rectangle that can be included in the XAML markup

This is accomplished by using the new abstract class XamlCompositionBrushBase available in the Creators Update. To use it, you subclass XamlCompositionBrushBase to create your own XAML Brush that can be used in your markup. As seen the example code below, the XamlCompositionBrushBase exposes a CompositionBrush property that you set with your effect (or any CompositionBrush) and it will be applied to the XAML element.

This effectively replaces the need to manually create SpriteVisuals with SetElementChild for most effect scenarios. In addition to needing less code to create and add an effect to the UI, using a Brush means you get the following added benefits for free:

  • Theming and Styling
  • Binding
  • Resource and Lifetime management
  • Layout aware
  • PointerEvents
  • HitTesting and other XAML-based advantages

Microsoft, as part of the Fluent Design System, has included a few Brushes in the Creators Update that leverage the features of XamlCompositionBrushBase:

Building a Custom Composition Brush

Let’s create a XamlCompositionBrush of our own to see how simple this can be.  Here’s what we’ll create:

To start, let’s create a very simple Brush that applies an InvertEffect to content under it. First, we’ll need to make a public sealed class that inherits from XamlCompositionBrushBase and override two methods:

  • OnConnected
  • OnDisconnected

Let’s dive into the code. First, create your Brush class, which inherits from XamlCompositionBrushBase:


public class InvertBrush : XamlCompositionBrushBase
{
    protected override void OnConnected()
    {
        if (CompositionBrush == null)
        {
            // 1 - Get the BackdropBrush, this gets what is behind the UI element
            var backdrop = Window.Current.Compositor.CreateBackdropBrush();

            // CompositionCapabilities: Are effects supported? If not, return.
            if (!CompositionCapabilities.GetForCurrentView().AreEffectsSupported())
            { 
               return;
            }
                
            // 2 - Create your Effect
            // New-up a Win2D InvertEffect and use the BackdropBrush as its Source
            // Note – To use InvertEffect, you'll need to add the Win2D NuGet package to your project (search NuGet for "Win2D.uwp")
            var invertEffect = new InvertEffect
            {
                Source = new CompositionEffectSourceParameter("backdrop")
            };

            // 3 - Set up the EffectFactory
            var effectFactory = Window.Current.Compositor.CreateEffectFactory(invertEffect);

            // 4 - Finally, instantiate the CompositionEffectBrush
            var effectBrush = effectFactory.CreateBrush();

            // and set the backdrop as the original source 
            effectBrush.SetSourceParameter("backdrop", backdrop);

            // 5 - Finally, assign your CompositionEffectBrush to the XCBB's CompositionBrush property
            CompositionBrush = effectBrush;
         }
    }

    protected override void OnDisconnected()
    {
        // Clean up
        CompositionBrush?.Dispose();
        CompositionBrush = null;
    }
}

There are a few things to call out in the code above.

  • In the OnConnected method, we get a CompositionBackdropBrush. This allows you to easily get the pixels behind the UIElement.
  • We use fallback protection. If the user’s device doesn’t have support for the effect(s), then just return.
  • Next, we create the InvertEffect and use the backdropBrush for the Effect’s Source.
  • Then, we pass the finished InvertEffect to the CompositionEffectFactory.
  • Finally, we get an EffectBrush from the factory and set the XamlCompositionBrushBase.CompositionBrush property with our newly created effectBrush.

Now you can use it in your XAML. For example, let’s apply it to a Grid on top of another Grid with a background image:


<Grid>
    <Grid.Background>
        <ImageBrush ImageSource="ms-appx:///Images/Background.png"/>
    </Grid.Background>
    <Grid Width="300" Height="300" 
               HorizontalAlignment="Center"
               VerticalAlignment="Center">
        <Grid.Background>
            <brushes:InvertBrush />
        </Grid.Background>
    </Grid>
</Grid>

Now that you know the basics of creating a brush, let’s build an animated effect brush next.

Creating a Brush with Animating Effects

Now that you see how simple it is to create a CompositionBrush, let’s create a brush that applies a TemeratureAndTint effect to an image and animate the Temperature value:

We start the same way we did with the simple InvertBrush, but this time we’ll add a DependencyProperty,  ImageUriString, so that we can load an image using LoadedImageSurface in the OnConnected method.


public sealed class ImageEffectBrush : XamlCompositionBrushBase
    {
        private LoadedImageSurface _surface;
        private CompositionSurfaceBrush _surfaceBrush;
 
        public static readonly DependencyProperty ImageUriStringProperty = DependencyProperty.Register(
            "ImageUri",
            typeof(string),
            typeof(ImageEffectBrush),
            new PropertyMetadata(string.Empty, OnImageUriStringChanged)
        );
 
        public string ImageUriString
        {
            get => (String)GetValue(ImageUriStringProperty);
            set => SetValue(ImageUriStringProperty, value);
        }
 
        private static void OnImageUriStringChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var brush = (ImageEffectBrush)d;
            // Unbox and update surface if CompositionBrush exists     
            if (brush._surfaceBrush != null)
            {
                var newSurface = LoadedImageSurface.StartLoadFromUri(new Uri((String)e.NewValue));
                brush._surface = newSurface;
                brush._surfaceBrush.Surface = newSurface;
            }
        }
 
        protected override void OnConnected()
        {
            // return if Uri String is null or empty
            if (string.IsNullOrEmpty(ImageUriString))
                return;
 
            // Get a reference to the Compositor
            Compositor compositor = Window.Current.Compositor;
 
            // Use LoadedImageSurface API to get ICompositionSurface from image uri provided
            _surface = LoadedImageSurface.StartLoadFromUri(new Uri(ImageUriString));
 
            // Load Surface onto SurfaceBrush
            _surfaceBrush = compositor.CreateSurfaceBrush(_surface);
            _surfaceBrush.Stretch = CompositionStretch.UniformToFill;
 
            // CompositionCapabilities: Are Tint+Temperature and Saturation supported?
            bool usingFallback = !CompositionCapabilities.GetForCurrentView().AreEffectsSupported();
            if (usingFallback)
            {
                // If Effects are not supported, Fallback to image without effects
                CompositionBrush = _surfaceBrush;
                return;
            }
 
            // Define Effect graph (add the Win2D.uwp NuGet package to get this effect)
            IGraphicsEffect graphicsEffect = new SaturationEffect
            {
                Name = "Saturation",
                Saturation = 0.3f,
                Source = new TemperatureAndTintEffect
                {
                    Name = "TempAndTint",
                    Temperature = 0,
                    Source = new CompositionEffectSourceParameter("Surface"),
                }
            };
 
            // Create EffectFactory and EffectBrush 
            CompositionEffectFactory effectFactory = compositor.CreateEffectFactory(graphicsEffect, new[] { "TempAndTint.Temperature" });
            CompositionEffectBrush effectBrush = effectFactory.CreateBrush();
            effectBrush.SetSourceParameter("Surface", _surfaceBrush);
 
            // Set EffectBrush to paint Xaml UIElement
            CompositionBrush = effectBrush;
 
            // Trivial looping animation to demonstrate animated effect
            ScalarKeyFrameAnimation tempAnim = compositor.CreateScalarKeyFrameAnimation();
            tempAnim.InsertKeyFrame(0, 0);
            tempAnim.InsertKeyFrame(0.5f, 1f);
            tempAnim.InsertKeyFrame(1, 0);
            tempAnim.Duration = TimeSpan.FromSeconds(5);
            tempAnim.IterationBehavior = AnimationIterationBehavior.Count;
      tempAnim.IterationCount = 10;
             effectBrush.Properties.StartAnimation("TempAndTint.Temperature", tempAnim);
        }
 
        protected override void OnDisconnected()
        {
            // Dispose Surface and CompositionBrushes if XamlCompBrushBase is removed from tree
            _surface?.Dispose();
            _surface = null;
 
            CompositionBrush?.Dispose();
            CompositionBrush = null;
        }
    }

There are some new things here to call out that are different from the InvertBrush:

  • We use the new LoadedImageSurface API to easily load an image in the OnConnected method, but also when the ImageUriString value changes. Prior to Creators Update, this required a hand-in Visual (a SpriteVisual, painted with an EffectBrush, which was handed back into the XAML Visual Tree). See the LoadedImageSurface section later in this article for more details.
  • Notice that we gave the effects a Name value. In particular, TemperatureAndTintEffect, uses the name “TempAndTint.” This is required to animate properties as it is used for the reference to the effect in the AnimatableProperties array that is passed to the effect factory. Otherwise, you’ll encounter a “Malformed animated property name” error.
  • After we assign the CompositionBrush property, we created a simple looping animation to oscillate the value of the TempAndTint from 0 to 1 and back every 5 seconds.

Let’s take a look at an instance of this Brush in markup:


<Grid>
            <Grid.Background>
                <brushes:ImageEffectBrush ImageUriString="ms-appx:///Images/Background.png"/>
            </Grid.Background>
</Grid>

For more information on using XamlCompositionBrushBase, see here. Now, let’s take a closer look at how easy it is now to bring in images to the Visual layer using LoadedImageSurface

Loading images with LoadedImageSurface

With the new LoadedImageSurface class, it’s never been easier to load an image and work with it in the visual layer. The class has the same codec support that Windows 10 has via the Windows Imaging Component (see full list here), thus it supports the following image file types:

  • Joint Photographic Experts Group (JPEG)
  • Portable Network Graphics (PNG)
  • Bitmap (BMP)
  • Graphics Interchange Format (GIF)
  • Tagged Image File Format (TIFF)
  • JPEG XR
  • Icons (ICO)

NOTE: When using an animated GIF, only the first frame will be used for the Visual, as animation is not supported in this scenario.

To load in an image, you can use one of the four factory methods:

As you can see there are two ways to load an image: with a Uri or a Stream. Additionally, you have an option to use an overload to set the size of the image (if you don’t pass in a Size, it will decode to the natural size).


CompositionSurfaceBrush imageBrush = compositor.CreateSurfaceBrush();
LoadedImageSurface loadedSurface = LoadedImageSurface.StartLoadFromUri(new Uri("ms-appx:///Images/Photo.jpg"), new Size(200.0, 200.0));
imageBrush.Surface = loadedSurface;

This is very helpful when you need to load an image that will be used for your CompositionBrush (e.g. CompositionEffectBrush) or SceneLightingEffect (e.g. NormalMap for textures) as you no longer need to manually create a hand-in Visual (a SpriteVisual painted with an EffectBrush). In an upcoming post in this series, we will explore this further using NormalMap images with to create advanced lighting to create unique and compelling materials.

Using LoadedImageSurface with a Composition Island

LoadedImageSurface is also useful when loading an image onto a SpriteVisual inserted in XAML UI using ElementCompositionPreview. For this scenario, you can use the Loaded event to adjust the visual’s properties after the image has finished loading.

Here is an example of using LoadedImageSurface for a CompositionSurfaceBrush, then updating the SpriteVisual’s size with the image’s DecodedSize when the image is loaded:


private SpriteVisual spriteVisual;
private void LoadImage(Uri imageUri)
{
    CompositionSurfaceBrush surfaceBrush = Window.Current.Compositor.CreateSurfaceBrush();

    // You can load an image directly and set a SurfaceBrush's Surface property with it
    var loadedImageSurface = LoadedImageSurface.StartLoadFromUri(imageUri);
    loadedImageSurface.LoadCompleted += Load_Completed;
    surfaceBrush.Surface = loadedImageSurface;

    // We'll use a SpriteVisual for the hand-in visual
    spriteVisual = Window.Current.Compositor.CreateSpriteVisual();
    spriteVisual.Brush = surfaceBrush;

    ElementCompositionPreview.SetElementChildVisual(MyCanvas, spriteVisual);
}

private void Load_Completed(LoadedImageSurface sender, LoadedImageSourceLoadCompletedEventArgs args)
{
    if (args.Status == LoadedImageSourceLoadStatus.Success)
    {
        Size decodedSize = sender.DecodedSize;
        spriteVisual.Size = new Vector2((float)decodedSize.Width, (float)decodedSize.Height);
    }
}

There are some things you should be aware before getting started with LoadedImageSurface. This class makes working with images a lot easier, however you should understand the lifecycle and when images get decoded/sized. We recommend that you take a couple minutes and read the documentation before getting started.

Wrapping up

Using Composition features in your XAML markup is easier than ever. From painting your UIElements with CompositionBrushes and applying lighting, to smooth off-UIThread animations, the power of the Composition API is more accessible than ever.

In the next post, we’ll explore more new APIs like the new Translation property, using XamlLights in your XAML markup and how to create a custom light using the new PointerPositionPropertySet.

Resources

Smooth as Butter Animations in the Visual Layer with the Windows 10 Creators Update

The Windows 10 Creators Update marks the third major release of the Windows UI platform APIs. With each release, an attempt is frequently made to simplify features introduced in prior releases. This encourages Universal Windows Platform (UWP) developers to standardize on these features. The new hide and show implicit animations are an example of this.

At the same time, too much standardization can potentially lead to conformity, so with each new release more powerful visual features like the new custom animations are also added, which allow developers who are willing and able to dive into them to customize their user interfaces and stand out from the crowd. This inherent tension between ease of use and the power to customize rewards developers for their efforts while also making sure that no one gets left behind.

Hide and show animations for page transitions

Page transitions, often accompanied by state transitions as visual elements, are added to the visual tree of the new page. In fact, a lot of interactivity in UWP simply involves deciding which content to show and which content to hide as the state of the app changes. More often than not, this is tied to changing the value of the Visibility properties of the elements on the screen.

In the Creators Update, two new implicit animation techniques have been added to help you make these transitions more fluid: ElementCompositionPreview.SetImplicitShowAnimation and ElementCompositionPreview.SetImplicitHideAnimation. Whenever a UIElement is loaded or when that element’s Visibility property is set to Visible, the implicit animation associated with it using SetImplicitShowAnimation will play. Similarly, whenever the user navigates away from a page or when a UIElement is hidden, an animation associated with it using the SetImplicitHideAnimation method will be invoked. These two mechanisms make it easier for you to include motion as an inherent aspect of all your visual elements, while providing a seamless experience for your users.

Connected animations

Implicit animations are great for animating controls inside a page. For navigation transitions between pages, however, the Visual Layer provides a different mechanism known as connected animations to help you make your UI even sweeter. Connected animations help the user stay oriented when she is performing common tasks such as context switching from a list of items to a details page.

The Windows UI platform APIs provide a class named the ConnectedAnimationService to coordinate animations between the source page and the destination page during navigation. You access the service by calling the static GetForCurrentView method. Then in the source page, you invoke PrepareToAnimate, passing in a unique key and the image that should be used for the transition animation.


ConnectedAnimationService.GetForCurrentView().PrepareToAnimate("MyUniqueId", image);

In the destination page, you retrieve the image from your ConnectedAnimationService service and invoke TryStart on the ConnectedAnimation while passing in the destination UIElement.


var animation = ConnectedAnimationService.GetForCurrentView().GetAnimation("MyUniqueId");
if (animation != null)
{
    animation.TryStart(DestinationImage);
};

In the Anniversary Update you did not have much control over this animation technique. Everyone got pretty much the same standard one. With the Creators Update, on the other hand, you have lots of new superpowers to personalize your transitions with:

  • Coordinated animations
  • Custom animations
  • Better image animations

Just to reiterate the point made in the introduction, the goal in designing the Windows UI platform APIs is to provide an awesome experience out of the box so you can copy the standard samples and get beautiful, fast and visually appealing visuals. At the same time, this shouldn’t ever take away from your ability to personalize the user experience to create something truly unique and wonderful with powerful new tools, like coordinated animations and custom animations.

Coordinated animations

A coordinated animation is a type of animation that appears alongside your connected animation and which works in coordination with your connected animation target. A coordinated animation gives extra visual flair to your page transition.

In the coordinated animation sample above, caption text that is not present in the source page is added to the destination page. The caption text is animated in tandem with the connected animation. We are doing two things here (in designer terms): providing context between the source and the destination using our connected animation while also adding visual interest with a coordinated animation at the destination. In user experience terms, though, all we’re doing is making the app’s transition animations look really cool.

Coordinated animations are fortunately also easy to implement. The TryStart method of the ConnectedAnimation class provides an override that allows you to pop in an array of visual elements you want to animate in a coordinated fashion. Let’s say that your caption text is in a visual element that you’ve named “DescriptionRoot.” You can add this as a coordinated animation by tweaking the previous code like so:


var animation = ConnectedAnimationService.GetForCurrentView().GetAnimation("MyUniqueId");
if (animation != null)
{
    animation.TryStart(DestinationImage, new UIElement[] { DescriptionRoot });
};

That’s a lot of power packed into a little argument.

Custom animations

By default, the connected animations in the navigation sample move in a straight line from the origin position in the source page to the target position in the destination page. If you select a box in the far-left column, it will move more or less straight up, while if you select a box in the top row, it will more or less move directly left to get to that target position. But what if you could put some English on this?

You can with custom animations, introduced in the Creators Update. The custom animations feature lets you modulate your transitions in four ways:

  • Crossfade – Lets you customize how elements crossfade as source element reaches destination
  • OffsetX – Lets you customize the X channel of Offset
  • OffsetY – Lets you customize the Y channel of Offset
  • Scale – Lets you customize scale of the element as it animates

In order to customize a particular part of a connected animation, you will need to create a keyframe animation and add it to your page transition using the SetAnimationComponent call like so:


var animation = ConnectedAnimationService.GetForCurrentView().GetAnimation("MyUniqueId");

var customXAnimation = Window.Compositor.CreateScalarKeyFrameAnimation();
customXAnimation.Duration = ConnectedAnimationService.GetForCurrentView().DefaultDuration;
customXAnimation.InsertExpressionKeyFrame(0.0f, "StartingValue");
customXAnimation.InsertExpressionKeyFrame(0.5f, "FinalValue + 25");
customXAnimation.InsertExpressionKeyFrame(1.0f, "FinalValue");

animation.SetAnimationComponent(ConnectedAnimationComponent.OffsetX, customXAnimation);

Note that you use expressions to get the starting and ending values of the connected animation.

Awesome image animations

The Creators Update also introduces improved image interpolation for connected animations where the image size and even the relative dimensions are changing between the source and the destination—for instance transitioning from a square to a rectangular image.

This interpolation happens automagically so you have less to worry about.

Implicit animation support for property sets and shadows

Finally, animation capabilities are also extended in the Creators Update by allowing you to apply implicit animations to property sets and shadows.

This change provides developers with even more creative flexibility and the ability to modify shadows in interesting new ways, as shown in the code sample below.


var shadowBlurAnimation = compositor.CreateScalarKeyFrameAnimation();
shadowBlurAnimation.InsertExpressionKeyFrame(1.0f, "this.FinalValue");
shadowBlurAnimation.Duration = TimeSpan.FromSeconds(1);
shadowBlurAnimation.Target = "BlurRadius";

//Associating animations with triggers 
implicitAnimationShadow["BlurRadius"] = shadowBlurAnimation;
implicitAnimationShadow["Opacity"] = shadowOpacityAnimation;
implicitAnimationShadow["Scale"] = shadowScaleAnimation;

implicitAnimationVisual["Translation"] = translationAnimation;
            

//Applying Implicit Animations to objects 
content.Properties.ImplicitAnimations = implicitAnimationVisual;
shadow.DropShadow.ImplicitAnimations = implicitAnimationShadow;

Wrapping up

The visual power being made available to developers through the Windows UI platform APIs have basically always been a part of the UI Framework. They just haven’t always been accessible until now. Think of this as a UI nuclear reactor being handed over to you to play with. With this awesome power, however, also comes the responsibility to create sweet UI and beautiful interactions. Go forth and be amazing.

To learn more about the topics covered in this post, you are encouraged to voraciously consume the following articles and videos:

Sweet UI made possible and easy with Windows.UI and the Windows 10 Creators Update

Since its original debut with the Windows 10 November 2015 update, Windows.UI.Composition has been empowering developers to build fast, beautiful, sweet user interfaces in UWP and has been providing enhancements with every subsequent Windows release. At Build 2017, we revealed what all of this continuous work has been leading up to: The Fluent Design System (aka ‘Project Neon’).

Moving from classic ‘Flat Design’ to Fluent Design requires the visual and performance capabilities that the Composition APIs offers along with the interop features that let you draw on this power from your XAML layer. In case you are not yet familiar with the concepts behind the Composition APIs, here’s a quick refresher on what the Composition APIs are all about.

The Windows.UI.Composition namespace allows Universal Windows Platform (UWP) developers to use a new Visual Layer that will get them closer to the metal, graphically speaking, while still using familiar technologies like XAML and C#. By getting closer to the metal, actually down to the system compositor level, developers are able to get great visual performance and custom UI experiences. By working through the XAML layer, developers get the ease of use they have come to expect out of UWP. This is basically a best of both worlds scenario that puts great responsibility in the developer’s hands. And with great responsibility, as we all know, comes great power.

So why do you need all these graphical and UX superpowers? In addition to giving pizazz to your UWP apps, access to the system compositor level also helps your users to accomplish their tasks faster and more fluidly. For instance, when you use Composition effects to blur a background in response to a click, you are focusing the user’s attention on her current task and removing distractions. This is the sort of subtle UI implementation that actually makes your user’s life easier – and it works best when your user doesn’t even know that you did anything for them. They are just left with the impression that your app is easy to use and feels fast, even if they can’t exactly put their finger on the reason.

The Visual family

To better understand the basic principles of Windows.UI.Composition, it’s important that we also introduce you to the visual family. In order to get fast and fluid effects, you need direct access to something called the system compositor (sometimes also referred to as the DWM). The system compositor is agnostic to the UI thread and doesn’t really care about being on the UI thread or blocking threads. Things happen very quickly at the system compositor level, where everything that is about to be sent to the display screen gets put together. This is also where you get to add additional effects if you want to just before shipping all your visuals to the display.

The visual family lives down at that compositor level where things happen rapidly. The visual family is made up of Visuals, ContainerVisuals and SpriteVisuals. The SpriteVisual class inherits from container visual, and the ContainerVisual class inherits from the base Visual class. There is also a Compositor class which acts as the senior member of the visual family. It quite literally creates visual objects if you need them and also manages the relationship between an application and the system compositor process.

The visual family is a lot of fun. Let’s say your XAML, many levels above, has a Grid object. That Grid will have a member of the visual family assigned to it. In technical parlance, we say that the Grid is backed by a visual. Once you grab hold of this backing visual, you can start to animate it using the composition animation system. If it is a ContainerVisual, then you can add additional visuals to it. Finally, you can also create sprite visuals, using the compositor factory class, in order to add brush effects to your visual using the Windows.UI.Composition effects system.

What’s new for sweet UI in the Windows 10 Creators Update

Several highly requested UI.Composition features have been added in the Creators Update to support fast and fluid UI as well as the Fluent Design System, for instance:

  • SVG support
  • Normal and Virtual Surfaces
  • Hover Interactions
  • Implicit Show and Hide
  • Expression Helpers
  • Offset stomping fix

At first these can seem like small disconnected improvements. Brought together, however, they will make creating beautiful UI both faster and easier.

XAML support for static SVG files

Vector images are often better for icons and logos because they can be resized without losing image quality. Before the Windows 10 Creators Update, however, vector graphics were not supported in XAML and working with iconography in UWP typically involved multiple versions of every image to adapt for multiple DPIs.  Now that that problem is solved, not only does XAML support static SVG files, but they also work with the Composition APIs.

Normal and virtual surfaces

The CompositionDrawingSurface has been a core component of the Composition APIs since the beginning, facilitating interop between XAML and Direct2D or Direct3D. The Creators Update is introducing the CompositionVirtualDrawingSurface for situations where only a portion of the content needs to be shown to the user at any given time. It basically bridges the concepts of graphics culling in video games and the development of infinite lists in desktop enterprise apps.

Independent hover interactions off the UI thread

One of the most powerful things about the Composition APIs is that they allow effects and animations to run independently of your main UI thread at 60 frames per second. With the Creators Update, this feature will also apply to hover animations in order to light up the many pointer activated effects that are a major part of fluent design.

There is also a subtle computer etiquette benefit to this new feature. Have you ever watched a busy animation play while your app’s UI was hanging and tried to move your mouse around in circles to try to make the animation go faster, but it has no effect? That is now a thing of the past.

Implicit show and hide

If you look at the code behind any UWP app, you will likely find that a large portion of UI code is devoted to setting visibility properties on UIElements in order to alternatively hide and show content. With this understanding, the Composition APIs now allow you to associate animations with your visual elements that are implicitly triggered when you hide or show them.


    ElementCompositionPreview.SetImplicitShowAnimation(MainContent, mainContentShowAnimations);
    ElementCompositionPreview.SetImplicitHideAnimation(MainContent, mainContentExitAnimation);

Implicit hide and show animations allow you to continue using this basic UI metaphor while also making it easier to create elegant visuals around them.

Expression helpers

Expression animations provide a way to create mathematical relationships between composition objects that can then be used to drive animations. The results of applying expression animations can often be breathtaking.

One piece of feedback we received about how we implemented expression animations is that it depends heavily on long strings of text like the following:


  rotationAnimation.Expression = "ACos( ( (A.Offset.X * B.Offset.X) + (A.Offset.Y*B.Offset.Y) + (A.Offset.Z * B.Offset.Z) ) / ( Length(A.Offset) *  Length(B.Offset) ) )";
  lineVisual.StartAnimation("RotationAngle", rotationAnimation);

The phrase “magic number” may even have been raised with respect to this. Just in time for the Creators Update, the Expression Builder Library is being introduced to provide you with type safety, IntelliSense and autocompletion as you create your own amazing expression animations.

Translation property

In earlier versions of the Composition APIs, there was a complication in the way UIElement properties were shared between the XAML layer and the Visual Layer that could cause the actual position of the visual to be overwritten or “stomped” in response to layout changes. While there was a workaround previously, there is now an actual fix with the new translation property. To prevent offset stomping, you now just need to enable the new Translation property through the ElementCompositionPreview class.


ElementCompositionPreview.SetIsTranslationEnabled(Rectangle1, true);

This is one of those issues that, if you’ve run into it before, you will feel a slight sense of relief. Just add a mental bookmark for yourself about the Translation property until you need to use it.

The sample gallery

The best way to deep dive into Windows.UI.Composition is by pulling down the sample code that the Composition team created and published to Github. The Windows UI Dev Labs samples, as they’re called, are extensive and visually rich. The samples extend from simple photo effects to complex parallax animations on XAML controls.

Don’t hesitate. It’s hard to really grasp the magnitude of the visual capabilities you are getting with Windows.UI.Composition until you see for yourself all that it empowers you to do.

Wrapping up

In addition to diving into the sample gallery on Github, which is highly recommended, you can also learn more about Windows Composition through the following articles, videos and blog posts.

Toolkits, Toolkits, Toolkits!

As a UWP developer, you have many options to help build your application quickly and reliably. In fact, there are so many options that you may feel like you can choose only one. Luckily, that’s not the case, and many toolkits complement each other in various ways.

Today, we’ll talk about two open source toolkits:

Both are open source, but each has different strengths. These two particular toolkits can bring tools and controls for a variety of application scenarios. Let’s start by introducing the toolkits and how they can help.

UWP Community Toolkit

The UWP Community Toolkit is the ultimate collaboration between Microsoft and the UWP developer community. With dozens of features such as helper functions, custom UI components, animations and app services, the UWP Community toolkit is a great time saver and can bring your application to the next level.

The toolkit has had 12 releases so far and is currently on v 1.4 (released on April 3, 2017). It has more than 80 contributors, with thousands of commits, and the community is constantly working on improvements. Conveniently, it’s broken up into several nuget packages so you can pick and choose exactly what you need.

Examples of this toolkit’s power can be found in the Services namespace, where you can easily interact with social media services with as little as two lines of code.

Here’s an example of getting a Twitter user’s timeline:


TwitterService.Instance.Initialize("consumer-key", "consumer-secret", "callback-uri");
ListView.ItemsSource = await TwitterService.Instance.GetUserTimeLineAsync("user-screenname", 50);

You can find a full demo application here in the source code or here in the Windows Store. Go here to see a full list of the available features (controls, helpers, etc.) and go here to find the documentation.

Telerik UI for UWP

Telerik UI for UWP, from Progress Software, is a recently open sourced toolkit that contains an amazing set of Line of Business (LOB) controls with which you can create native, business-focused, UWP applications. With controls such as DataGrid and RadListView, the Telerik UI provides the powerful sorting, grouping and editing experiences you might expect from a desktop application, as well as rich data visualization experiences with controls such as Charts, Gauges and BulletGraphs.

We recommend you check out the Customer Database Example application here on GitHub to see the DataGrid in action, as well as the SDK Examples app here. You can see a full list of available controls here and find the documentation here (if you’re looking for a little extra help, Progress Software also offers professional support in the premium package).

An example of this toolkit’s power is the RadDataGrid. With one line of code you get a bunch of out-of-the-box features like grouping, sorting and filtering.

You can install UI for UWP in your application using the nuget package or build from the source directly. If you would like to read more about why Progress Software open sourced Telerik UI for UWP, we recommend you check out this great article.

Contributing

If you’re a developer who likes contributing to GitHub repos and giving back to the community, or if you have ideas to make things better for other developers, both toolkits accept pull requests and each has its own contribution guidelines (here for UWP community toolkit and here for Telerik UI for UWP).

Wrapping up

Both toolkits complement each other. You can use them side by side in your application to bring the user a delightful, yet powerful, experience in your UWP application. With dozens of UI controls, helpers, services and more, you can get your UWP app to market faster and with more confidence than ever. We look forward to seeing your UWP Community Toolkit and UI for UWP powered applications in the Windows Store!

Resources

Introducing XAML Standard and .NET Standard 2.0

XAML Standard

We are pleased to announce XAML Standard, which is a standards-based effort to unify XAML dialects across XAML based technologies such as UWP and Xamarin.Forms.

XAML Standard is a specification that defines a standard XAML vocabulary. With that vocabulary, frameworks that support XAML Standard can share common XAML-based UI definitions. The goal is for the first version, XAML Standard 1.0, to be available later this year.

Post-specification plans include support of XAML standard in Xamarin.Forms and UWP. You can continue developing your UWP and Xamarin.Forms apps as you do today. When XAML Standard support is enabled, you will be able to reuse and share between the frameworks and expand into more platforms.

To visualize what this support would look like, here’s a side-by-side comparison between today’s XAML in Xamarin.Forms and in UWP:

In the above example – once XAML Standard is supported by Xamarin.Forms, you can use <TextBlock /> and have it supported in a Xamarin.Forms app targeting iOS and Android instead of needing to know and use <Label /> as shown above. In addition to a TextBlock, here are some of the currently proposed items for standardization.

We are at the beginning of a journey that makes it easy for you to reuse your XAML source files between some simple Xamarin.Forms and UWP views. For example – a Settings.xaml page, where you typically have some text, toggle switches and some buttons. You’d only need to design and create one XAML file to describe this UI and that can be used everywhere.

Nothing changes for existing developers – you can continue to use the same APIs you have always used in both frameworks. XAML Standard will help you reuse/share any common UI code that you wish to share between end points.

The XAML Standard v1 draft spec is being defined in the open, we encourage you to start a discussion or give us direct feedback in the GitHub repo here.

.NET Standard 2.0

We are also happy to announce .NET Standard 2.0! .NET Standard is the set of APIs which work in all .NET implementations. A good way to think about it is how HTML5 is today. There are many different browsers which implement HTML parsing and rendering, but the HTML standard is the common glue that holds the web together and allows for interoperability.

.NET Standard was introduced in June of 2016 to bring consistency to the .NET ecosystem. With the .NET Framework, Xamarin & Mono, .NET Core and then UWP, there were many different implementations of .NET and it was very difficult to write code or a library that could work across all of them. Using .NET Standard, and the tooling in Visual Studio, makes it possible to build libraries and NuGet packages that work literally everywhere .NET runs.

The feedback we received on after .NET Standard’s introduction last year was generally phrased as “We like the direction you’re going in, but the set of APIs isn’t large enough to be useful.” The goal with .NET Standard 2.0 is to respond to that feedback and add a large set of .NET’s “greatest hits” into .NET Standard. To do this, we looked at the intersection of APIs between the .NET Framework and Mono. This lead to the 2.0 definition including over 20,000 new APIs and those APIs enable the top 70% of existing NuGet packages to work.

With the addition of .NET Standard 2.0 support for UWP with the Fall Creators Update, .NET developers will be able to share code across all Windows 10 devices, in the cloud and through the rest of the .NET ecosystem. This will also make it easier to reuse existing WinForms and WPF code as many of the most frequently used APIs like DataSet/DataTable, and popularly requested APIs like SqlClient, are now part of .NET Standard 2.0.

You can learn more about .NET Standard here.

Forming the shape of the future

We invite you, the .NET community, to join the discussion and help shape the future of XAML Standard and .NET Standard. You can provide your feedback, both suggestions and issues, at the following locations; .NET Standard on Github and XAML Standard on Github.

Resources:

Master the Master-Detail Pattern

In the world of information consumption in applications, it’s crucial to have a clear and easy way to navigate and inspect that information. The master-detail design pattern has become one of the most popular approaches in applications today. In this post, we’ll discuss what this is, determine if it’s appropriate for your application and show how you can use it!

What is a master-detail?

The answer to this will depend on what kind of information your application is trying to show, but at a high level, the “master” is an area in the UI where you have a list of something and the “detail” is the area that shows the relevant information of a selection in the master.

You can find a great example of the master-detail pattern in the Windows 10 email app, “Mail.”  The master is the list of emails and the details is the selected email.

The master-detail pattern is easy to understand and doesn’t need a lot of explanation to the user. When the user selects something in the master, they see the information and any actions relevant to that detail item. For example, selecting an email shows the body of the email as well as the buttons for: reply, reply-all and delete.

The pattern works well for these types of application scenarios:

  • You have a list where it makes sense to show details (e.g. list of contacts, products, etc.)
  • You have a large list that has items that need to be prioritized (e.g. RSS readers)
  • You need to switch between items frequently but want to stay in the same context (e.g. email)

Let’s use the Microsoft RSS Reader UWP example app to illustrate the master-detail pattern’s features.

If you want to follow along or see the code first-hand, find the RSS Sample’s source code here on GitHub.

Master-detail modes

The master-detail pattern works well on a wide range of device types and display sizes. However, you should consider how you want to use the pattern on different display sizes.

There are two popular modes that will help with this:

  • Side-by-side
  • Stacked

The determination between which approach to take comes down to how much horizontal room your app has. Here’s a table of typical effective pixels available per “size class” (if you’re not familiar with Effect Pixels (epx) see this one minute video).

Size class small medium large
Typical screen size (diagonal) 4″ to 6″ 7″ to 12″, or TVs 13″ and larger
Typical devices Phones Phablets, tablets, TVs PCs, laptops, Surface Hubs
Common window sizes in effective pixels 320×569, 360×640, 480×854 960×540, 1024×640 1366×768, 1920×1080
Window width breakpoints in effective pixels 640px or less 641px to 1007px 1008px or greater

Side by side

There many scenarios in which your application will have plenty of horizontal space to stretch.  The recommended guidelines for this mode is when your application has 720 epx or more available; this puts us in to the “Medium” and “Large” size classes seen above.

A few of these are:

  • Devices that let you size the app window larger (PC, HoloLens, Surface Hub)
  • Windows 10 Mobile running Continuum
  • Windows 10 Mobile (landscape orientation)

In the side-by-side approach, you can have both the master view and the detail view showing simultaneously. Using our RSS example, here’s the side-by-side approach:

Stacked

If your application is running in between 320 to 719 epx, you can’t comfortably fit the master and details next to each other, so we’ll need another way to display the master and detail.

A few examples of this scenario are:

  • Any device that lets you resize the app window (e.g. PC, HoloLens)
  • Windows 10 Mobile (portrait orientation)

For this case, you can use the stacked approach. In stacked, the master view gets the full screen space, then, when a selection is made, the detail view gets the full screen space.

With this approach, we’re “stacking” the pages in a single area and navigating between them. For example, the user selects an item in the master, the app will navigate to the Details View. When they want to see another item, they’ll navigate back to the master and select another item.

The stacked approach can be implemented with page navigation within a Frame element. In the diagram below, the “page control” you see is where the navigation occurs between the master view and the detail view.

Using our RSS sample app, here are a couple screenshots of the master and detail in stacked mode. Note that the app is running on a desktop PC, but with the window sized small, you’ll see the same appearance as it were on a mobile device. What matters is not the device, but the available screen space!

The “Breaking Point”

You’ll notice that we have this point where we need to change between the two different modes, depending on the current app width. For our master-detail, we’ve decided to do this at 720 epx. This means that once the application window gets resized to above or below 720 epx, we should be switching between side-by-side or stacked mode.

The Universal Windows Platform has a great feature to help with changing modes: the AdaptiveTrigger. Using an AdaptiveTrigger in your view’s VisualStates, you can adapt the UI when the application’s window size reaches that “breaking point.”  In the RSS sample, you can see how this is done on the MasterDetailPage.xaml.

First, let’s look at the master-detail layout; there’s a Frame element for the master content (ListView of feeds and articles) and a WebView for the detail content (the selected article). Notice the default width of the MasterColumn is set to 360.


    &lt;Grid.ColumnDefinitions&gt;
        &lt;ColumnDefinition x:Name=&quot;MasterColumn&quot;
                          Width=&quot;360&quot; /&gt;
        &lt;ColumnDefinition x:Name=&quot;DetailColumn&quot;
                          Width=&quot;*&quot; /&gt;
    &lt;/Grid.ColumnDefinitions&gt;

    &lt;Frame x:Name=&quot;MasterFrame&quot; /&gt;

    &lt;WebView x:Name=&quot;ArticleWebView&quot;
             Grid.Column=&quot;1&quot;
             Visibility=&quot;Collapsed&quot; /&gt;
&lt;/Grid&gt;

Now, let’s look at line 49 in the VisualStateGroups. You’ll see the VisualState named “NarrowState.” In this visual state, the MasterColumn.Width changes to * (star, which means “take all the available space”) and the DetailColumn.Width changes to 0.

Because the AdaptiveTrigger is set to 720, anything between 0 and 719 will use the NarrowState and anything 720 or larger will use the DefaultState.


&lt;VisualStateManager.VisualStateGroups&gt;
    &lt;VisualStateGroup&gt;
        &lt;VisualState x:Name=&quot;DefaultState&quot;&gt;
            &lt;VisualState.StateTriggers&gt;
                &lt;AdaptiveTrigger MinWindowWidth=&quot;720&quot; /&gt;
            &lt;/VisualState.StateTriggers&gt;
        &lt;/VisualState&gt;
        &lt;VisualState x:Name=&quot;NarrowState&quot;&gt;
            &lt;VisualState.StateTriggers&gt;
                &lt;AdaptiveTrigger MinWindowWidth=&quot;0&quot; /&gt;
            &lt;/VisualState.StateTriggers&gt;
            &lt;VisualState.Setters&gt;
                &lt;Setter Target=&quot;MasterColumn.Width&quot; Value=&quot;*&quot; /&gt;
                &lt;Setter Target=&quot;DetailColumn.Width&quot; Value=&quot;0&quot; /&gt;
            &lt;/VisualState.Setters&gt;
        &lt;/VisualState&gt;
    &lt;/VisualStateGroup&gt;
&lt;/VisualStateManager.VisualStateGroups&gt;

To see this in action, run the RSS reader example and resize the window from big to small and back. You’ll see the visual states change and switch between the side-by-side and stacked modes.

Additional Detail Functionality

In the beginning of this article, we briefly touched on how you can have context-aware functionality when using a master-detail. The example was having a “reply” button for an email app. However, you can go much further with it. Here are some more examples of functionality you can put into the detail view:

  • Product list: Order, track, add to wish list
  • Contact list detail options: Call, email, drive to
  • Inventory list detail: Reorder, mark damaged, ship

Another takeaway is that you can share the same controls (e.g. Buttons) for frequently used functionality and that functionality would intuitively be for that selected item in the detail view.

UWP Community Toolkit

If you’re building an application that could benefit from a master-detail implementation, you can skip a lot of the work by using the MasterDetailView control in the UWP Community Toolkit. With as little as a few lines of code and a couple DataTemplates (one for the master’s items and the one for the detail view), you can be up and running quickly.

Here’s the example from the UWP Community Toolkit demo app:


&lt;controls:MasterDetailsView
          ItemsSource=&quot;{Binding Items}&quot;
          ItemTemplate=&quot;{StaticResource ListTemplate}&quot;
          DetailsTemplate=&quot;{StaticResource DetailsTemplate}&quot;&gt;
&lt;/controls:MasterDetailsView&gt;

Resources

Windows Developers at Microsoft Build 2017

Microsoft Build 2017 kicks off on May 10 in Seattle, with an expected capacity crowd of over 5,000 developers—plus countless more online. Join us for the live-streamed keynotes, announcements, technical sessions and more. You’ll be among the first to hear about new developments that will help you engage your users, keep their information safe and reach them in more places. Big things have been unveiled and promoted at Microsoft Build over the years and this year’s conference won’t be any different!

There will be quite a bit of content specifically relevant to Windows developers:

  • Improvements that help you immediately engage your users with beautiful UI and natural inputs
  • Team collaboration and connectedness to streamline and improve your development experience
  • Services that make it easier to reach customers and learn what they want from your software
  • Connected screens and experiences that make your end-to-end experience stickier and more engaging
  • Mixed reality and creating deeply immersive experiences

Sign up for a Save-the-Date reminder on our Build site for Windows Developers and we’ll keep you in the loop as new details and information come in. When you sign up, you’ll also gain the ability to:

  • Save sessions for later viewing
  • Create and share content collections
  • Discuss what you’ve seen and heard with other developers
  • Upvote content you like and track trending sessions

You’ll find sign-up, sessions and content here.

New Share Experience in Windows 10 Creators Update

Here we’ll describe how we’ve made sharing in Windows 10 Creators Update better than ever before. In addition to refreshing the entire Share experience to make it easier to use, we’ve added new features and capabilities for developers. In this blog post, we’ll guide you through the new experience and examples of the updated Share developer features, with full source code available on GitHub.

UI redesign

First, let’s talk about the redesigned Share experience. We’ve rethought it from beginning to end – and that includes the Share icons that users will be utilizing. You can read a great blog post about the reasons and the process here, but in short, we’ve refreshed the Share icon in Windows to be more familiar and user-friendly!

Previous Windows Share icon on the left and the new Share icon on the right.

As a developer, if you use the standard icon for Share, you’ll get this change for free. The flow begins in the same way: tapping on the icon will launch the new Share dialog to show what apps can share this content.

For example, within Microsoft Edge, users can tap on the Share icon to share the web page they are currently on:

Launching Share from Microsoft Edge with the new icon

You should see the new Share dialog launch in the center of the invoking app. For developers, nothing has changed so far – the same code you used to launch Share in the past will now automatically launch the new Share dialog. This Share dialog contains some information about the content being shared as well as the apps that they can share this content with.

When the user selects an app (e.g. Mail or Facebook), it will invoke the Share target modally in the center of the app.

Store promotion

In the new Share dialog, you may have noticed there are a couple apps tagged with “Install.” In the past, we’ve noticed that users will leave the Share experience when they don’t see the app they want to share content with. To make it easier for everyone to find the right target, we’ve started promoting some of the top Share target apps in the Windows Store directly in the Share experience. For example, in the Share window displayed above, the user can choose to share with one of the installed apps (e.g. Facebook, Mail, Twitter, etc.), or download one of the suggested apps to Share (e.g. LINE, Messenger). Picking one of the promoted apps will take the user to the Store to install the corresponding app. Promoted apps are chosen based on their popularity in the user’s region (i.e. the most popular Share targets are promoted). Once the app is installed, the user will be able to share content with it. As a developer, you don’t need to do anything – the top apps will show up for your users immediately. This makes it easier than ever before for our users to share content to popular apps they might care about.

Developer features

Share Providers

We wanted to go even further to make it easier for users to find apps and targets that they might want to share with (Share Providers). Share Providers are app-defined targets that enable you, as the developer, to inject targets directly into the Share contract as part of your Share experience. This means that even if a given app or behavior is not currently available in the Windows ecosystem, you can include a Share Provider to bring this functionality to your users. Furthermore, if the app you want your users to share to is available on Windows but there are web SDKs that offer richer functionality, you can choose to include a Share Provider to build the experience you desire. As a developer, it’s easy to add one of these into Share:

First, register for the ShareProvidersRequested method in the OnNavigatedTo method of your page.


// Add Share Events in OnNavigatedTo
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            // Get the current Data Transfer manager
            this.manager = DataTransferManager.GetForCurrentView();

            // Setup Data package in DataRequested event as before
            manager.DataRequested += OnDataRequested;

            // Register for ShareProvidersRequested event 
            manager.ShareProvidersRequested += OnShareProvidersRequested;

        }

Then, handle the event when it’s raised and add Share Providers into the list provided in the event args.


// Handle this event to add a Share Provider
        private void OnShareProvidersRequested(DataTransferManager s,
            ShareProvidersRequestedEventArgs e)
        {
            // Deferral included for any long running tasks
            Deferral d = e.GetDeferral();

            // Show &quot;Copy Link&quot; Share Provider only if the shared content includes a link
            if (e.Data.Contains(StandardDataFormats.WebLink))
            {
                // Specify icon for the Share Provider
                RandomAccessStreamReference copyIcon = 
			RandomAccessStreamReference.CreateFromUri(new Uri(@&quot;ms-
appx:///Assets/StoreLogo.png&quot;));

// Create the Copy Link Share Provider with Display Name, icon and callback function
                ShareProvider copyProvider = new ShareProvider(&quot;Copy Link&quot;, copyIcon, 
			Windows.UI.Colors.Red, OnCopySelected);

                // Add to the list of Share Providers and pass them to DataTansferManager
                e.Providers.Add(copyProvider);
            }

            // Complete Deferral
            d.Complete();
        }

In the screenshot at the beginning of this section, you can see “Copy Link” as a Share target, which has been added to Share dialog using the code snippets shown above. To implement the Share Provider, all you need to do is implement the Callback function specified when you create the object. The code below simply takes the WebLink from the ShareDataPackage and places it on the Clipboard.


        // Implement Copy Link ShareProvider 
        private async void OnCopySelected(ShareProviderOperation operation)
        {
            Uri copyURI = await operation.Data.GetWebLinkAsync();
            DataPackage package = new DataPackage();
            package.SetText(copyURI.ToString());

await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync (CoreDispatcherPriority.Normal,
            () =&gt;
            {
                Clipboard.SetContent(package);
            });
        } 

Share completed

We also heard feedback from source apps that were interested in learning more about content that users share from their apps. Content that people choose to share is often important or valuable in some way, so we want to give developers information about the content and the target. To make this possible, we have introduced a new event called “OnShareOperationCompleted”. Your app can subscribe to this event to get information about the Share target and to build experiences around content that users have shared in the past.

Here’s how you use it:

First, register for ShareCompleted in your OnDataRequested method in your share implementation. This gets called when the target calls ReportCompleted.


private void OnDataRequested(DataTransferManager sender, DataRequestedEventArgs args)
        {
            // Get the current DataRequest
            DataRequest request = args.Request;

            // Setup sample share data
            request.Data.Properties.Title = &quot;Share Link Example&quot;;
            request.Data.SetText(&quot;Hello World&quot;);
            request.Data.SetWebLink(new Uri(&quot;http://www.bing.com&quot;));

            // Register Share Operation Completed
            request.Data.ShareCompleted += OnShareCompleted;
        }

Then, handle the event when it’s raised to see all of the information about the shared content. This simple implementation just prints out information about the target into the debug console.


// Use the OnShareCompleted event to get information about successful shares
        private void OnShareCompleted(DataPackage sender, ShareCompletedEventArgs args)
        {
            Debug.WriteLine(&quot;Share Completed&quot;);
            Debug.WriteLine(&quot;AUMID: &quot; + args.ShareTarget.AppUserModelId);
            Debug.WriteLine(&quot;Share Provider: &quot; + args.ShareTarget.ShareProvider.Title);
        }

Wrapping up

Sharing is important to us, and that’s why we’re excited to have everyone start using the new Share experience and other exciting features with the Creators Update. Universal Windows app developers can start building on these features today with in the most recent Windows Insider Builds. As always, we’ll keep listening to your feedback and embrace the opportunity to iterate and improve as needed. We hope all app developers and users alike will love the new changes to Share in Windows! Happy sharing, everyone.