Paint 3D Dialog Box using Composition Shadow

paint3d.JPG

After analyzing the Dialog Box from Paint 3D (DBP3), I decided to create one by myself. I think the DBP3 should use:

  1. The Content Dialog class instead of a custom one and trying to disable elements. It has appear and disappear transitions so it works pretty well.
  2. The Composition shadow instead 7 borders around the control.

The first thing we have to do is customize the parameters of the content dialog. To do that, you can find the file or just use UWP Technical guide:

(If you find the App useful consider about tapping the  menu – smile – remove ads, it really helps.)

contentdialogstyle.JPG

With that you know what are the properties to change and ThemeResources to replace its values.

Styles

So now in the App.xaml:

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.ThemeDictionaries>
            <ResourceDictionary x:Key="Dark">
                <SolidColorBrush x:Key="ApplicationPageBackgroundThemeBrush">#3111</SolidColorBrush>
                <Thickness x:Key="ContentDialogContentScrollViewerMargin">0</Thickness>
                <Thickness x:Key="ContentDialogPadding">0</Thickness>
            </ResourceDictionary>
            <ResourceDictionary x:Key="Light">
                <SolidColorBrush x:Key="ApplicationPageBackgroundThemeBrush" Opacity="0.5">3EEE</SolidColorBrush>
                <Thickness x:Key="ContentDialogContentScrollViewerMargin">0</Thickness>
                <Thickness x:Key="ContentDialogPadding">0</Thickness>
            </ResourceDictionary>
        </ResourceDictionary.ThemeDictionaries>
    </ResourceDictionary>
</Application.Resources>

Now in the Page we are, or here in App.xaml if you prefer, add the following style to override all paddings and margins:

<Page.Resources>
<Style TargetType="ContentDialog" x:Key="PaintDialogBoxStyle" x:Name="PaintDialogBoxStyle">
        <Setter Property="Padding" Value="12"/>
        <Setter Property="MaxHeight" Value="400" />
        <Setter Property="MinHeight" Value="0" />
        <Setter Property="MaxWidth" Value="500" />
        <Setter Property="MinWidth" Value="0" />
        <Setter Property="Padding" Value="0"/>
        <Setter Property="BorderBrush" Value="Transparent"/>
        <Setter Property="BorderThickness" Value="0"/>
        <Setter Property="FullSizeDesired" Value="False"/>
        <Setter Property="Background" Value="Transparent"/>
    </Style>

</Page.Resources>

The dialog

XAML

Let’s create a UserControl or a Templated Control with the following XAML structure:

<Grid Width="492" Height="340" Background="Transparent">
    <Canvas x:Name="ShadowHost" Margin="18" Background="Transparent"/>
    <Grid x:Name="LayoutRoot"  Margin="20"  Background="#FFF0F2F3">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="1*"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
        <Border BorderThickness="1" BorderBrush="{ThemeResource ContentDialogBorderBrush}" Grid.RowSpan="3"/>
        <Image Source="ms-appx:///Assets/Images/Paint_Logo_with_Trademark_ABOUT_POPUP.png" Height="80" VerticalAlignment="Top" Margin="0,42,0,0"/>
            <StackPanel Grid.Row="1" Margin="0,12,0,0">
                <HyperlinkButton Foreground="#FF4D4D75" Content="Contoso Software License Terms" FontSize="12" Padding="0" HorizontalAlignment="Center"/>
                <HyperlinkButton Foreground="#FF4D4D75" Content="Privacy Statement" FontSize="12" Padding="0" HorizontalAlignment="Center"/>
                <HyperlinkButton Foreground="#FF4D4D75" Content="Contoso Services Agreement" FontSize="12" Padding="0" HorizontalAlignment="Center"/>
                <TextBlock Foreground="#FF4D4D75" Text="1.1701.12017.0" FontSize="12" Padding="0" HorizontalAlignment="Center"/>
            </StackPanel>
            <Button Click="CloseDialog" Grid.Row="2" Margin="0,0,0,24" Width="200" Content="OK" HorizontalAlignment="Center"/>
        </Grid>
</Grid>

To explain the values:

  1. The original DBP3 has a size of 484×332 so to avoid adding many values I decided to set that size + 2×4 and the Margins 20 and 18 make the game to have the panel inside and the shadow outside.
  2. The rule of creating a Canvas for the host is based on the latest documentation from MSDN about The Visual Layer with XAML.
  3. To make easy the position of the button I decided to set it inside and avoid the buttons the DialogContent has.
  4. The rest is from the values the Visual Tree of Paint 3D.

Code

We have to make transparent the rectangle that appears when a Content Dialog is shown and when the button is Clicked make it disappear.

Note: Clicked is for (keyboard enter, mouse click and touch tap), and Tapped is for (tapped and click).

public sealed partial class AboutElement : UserControl
    {
        public AboutElement()
        {
            this.InitializeComponent();

            this.Loading += AboutElement_Loading;
            this.Loaded += AboutElement_Loaded;
        }

        private void AboutElement_Loading(FrameworkElement sender, object args)
        {
            var popup = VisualTreeHelper.GetOpenPopups(Window.Current).FirstOrDefault(p=> p.Child is Rectangle);

            if(popup?.Child is Rectangle rectangle)
            {
                rectangle.Fill = new SolidColorBrush(Colors.Transparent);
            }
        }

        private void AboutElement_Loaded(object sender, RoutedEventArgs e)
        {
            InitializeDropShadow(ShadowHost);
        }

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

            // Create a drop shadow
            var dropShadow = compositor.CreateDropShadow();
            dropShadow.Color = Color.FromArgb(128, 0, 0, 0);
            dropShadow.BlurRadius = 10.0f;
            dropShadow.Offset = new Vector3(0.0f);

            var shadowVisual = compositor.CreateSpriteVisual();
            shadowVisual.Shadow = dropShadow;

            ElementCompositionPreview.SetElementChildVisual(shadowHost, shadowVisual);

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

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

        private void CloseDialog(object sender, RoutedEventArgs e)
        {
            var popup = VisualTreeHelper.GetOpenPopups(Window.Current).FirstOrDefault(p => p.Child is ContentDialog);

            if (popup?.Child is ContentDialog dialog)
            {
                dialog.Hide();
            }

        }
    }

Calling

And finally to call it from a view:

private async void ShowDialog()
{
    var dialog = new ContentDialog { Content = new AboutElement(), Style = PaintDialogBoxStyle};
    await dialog.ShowAsync();
}

So with the existing API and without inventing new panels and controls, you can create the Dialog using the standard methods and not experiments like I explained in previous posts.

I prefer setting the border to transparent like the following, but it’s just my opinion:

paint3dprefer

Hope you find it useful, get ready for Feb 8, let’s see what happens.

@juanpaexpedite

Advertisements

Experiments with Creators Update 15025

I am trying to find the Neon features. There are different ways that could make it work and apart I will make tests with some features to understand what are their purposes.

ApplicationView

Here we have new functionality like making the app like a Compact Overlay Window:

compact

When the window is out of focus even the title bar disappears and shows the Top left and Top Right Text Boxes, You can resize it from 150×150 up to might be 500 x 500. No idea the purpose, might be advanced interactive notifications.

Compact2.jpg

private async void PageLoaded(object sender, RoutedEventArgs e)
{
    this.SizeChanged += MainPage_SizeChanged;

    await Task.Delay(5000);
    var view = Windows.UI.ViewManagement.ApplicationView.GetForCurrentView();
    await view.TryEnterViewModeAsync(ApplicationViewMode.CompactOverlay);
}

NotesWindowManagerPreview

Inside Application model we have:

var notes = Windows.ApplicationModel.Preview.Notes.NotesWindowManagerPreview.GetForCurrentApp();
var contract = new PreviewNotesContract();

Might be we can create some kind of notes, sticky notes? no idea. there are only int references and cannot make any advance on that. There are also inside the preview another one for InkWorkspace and Holographic.

HDMI information

var hdmiInfo = Windows.Graphics.Display.Core.HdmiDisplayInformation.GetForCurrentView();

It returns null, so no surprises. I understand this appeared because the Surface Studio and its HDMI color spaces management.

Unloading XAML

Another in progress

XamlMarkupHelper.UnloadObject(this.BRTextBlock);

It throws an exception, it might be for reading XAML and removing items, or to dispose items from a Panel, I do not know. no more methods, constructors, etc.

I prefer to no continue with this post because is a waste of time using this SDK.

 

 

 

 

 

 

Analyzing Paint 3D 2/2

The Paint 3D app has been updated, and they have solved the issue shown in the previous post Analyzing Paint 3D 1/2 , now if you press tab, it will only cycle around the control PaintDialog.

about.JPG

I have also taken a look to all the fonts in the system for Paint, Edge, and more fonts. At the moment all remain the same. You find them by searching *.ttf in Windows/SystemApps.

There are no news about using SVGImageSource instead Canvas Path for the tool icons. I understand will be changed in the CreatorsUpdate.

Before digging about the properties and structure of the controls, you can take a look to them with Visual Studio. Create a new project and add the references from the winmd files, then you will be able to open that:

metadata

It is only the information from the metatada, not the source code, so you won’t able to use that. But it is interesting because you can do it directly from VS.

Let’s analyze first the visuals left from the previous post and then the rest of the controls.

Shadows

In this release, we still have a rectangle with a lineargradientbrush for the shadows of the panels, they have the following properties:

shadow

If you do not usually apply linear gradient brushes, you can get more information at msdn uwp brushes.

Now you can apply the same shadow in your apps, let’s take a look to the controls that appear like a popup.

PaintDialog

It is a Content Control that simulates a popup dialog. It does not appear in the Canvas Panel of the Popups, it is inside the main visual tree and the controls have this inside to show its functionality limiting the actions inside it.

HsvColorPicker

hsv

This is a control that appears with a PaintDialog, it has a shadow, really complex because it has a Shadow Grid with 7 borders to make the shadow. It bothers my who decided and why to do that:

shadow2

The background brush of this control, is defined in the DropShadowBorder #FFF6F6F6, it is not an static resource, I cannot assure that, but apparently it is. The margin of the header is 24,28,0,0. So now are a factor x4. and the color of the title is Black with 0.6 of opacity.

The color selector is SaturationGradient.png inside Content folder that looks like the following:

gradient

And below contains the color which is binded to the color of other Control.

The slider to change the hue, has been customized with a gradient with 29 stops:

gradientinfo

I understand this gradient has been made with a tool, and not hardcoded. I would like to see more Win2D and Composition in this app but at the moment nothing really surprising.

After looking the rest of the information that can be extracted, and watching that the SwapChainPanel does not show any information when is used in 3D, I decided to give my conclusions and continue when the Creators Update and the new Universal Examples on GitHub get released.

Conclusions

There is no way to analyze styles, transitions, etc. from the Live Visual Tree. might be in the future will appear a third party tool to analyze it. (In case you know how please share)

I am waiting new real documentation ‘Acrylic’ with personas, XAML lights, shadows, SvgImageSource, updated Compiled binding and many more. Might be on Feb 8 we get more information.

The GitHub repositories are stopped, most of them have 6 months old and composition repo 4 months, that means ages.

Paint 3D app is not using any internal SDK it is using the typical we use. it is a really outdated version comparing it to the release I think we will see in a near future. Might be when release the new SDK without being prerelease.

And that’s all not surprises but details, as always @juanpaexpedite

UWP Protect files embedding them

When developing apps you search for practical, tested and for real environments information. That is always my purpose, improve and go beyond in universal apps.

Let’s begin reading files in universal apps.

It is just two lines to read a file in your app and assign to an string, but might you do not know that you can go inside the folder of that app, navigate to the Assets folder and grab that file.

An UWP app should be a safe sandbox in both ways, one for the user to feel safe its Windows and on the other side for the developer, keeping the files safe.

In theory there is no limit about the size of the file to protect, can be any you consider, because the reader is asynchronous it can last how long it takes.

Text File

Suppose you have a json with few data, you prefer use json because it’s fast. If you place it at Assets/Data and the build options to Content, it will be available for any user at that path like C:\Program Files\WindowsApps\[AppName]_[Version]_[Platform]__[Id]

Content file

When you want to read or delete a text file with the build action as Content:

public static async Task<string> LoadContentTextFileAsync(string contenturi)
{
    var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(contenturi));

    return await FileIO.ReadTextAsync(file);
}

public static async Task<bool> DeleteContentFile(string contenturi)
{
    var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(contenturi));

    if (file != null)
    {
        await file.DeleteAsync(StorageDeleteOption.PermanentDelete);
        return true;
    }
    return false;
}

Now let’s change it to Embedded resource, and of course do not copy the file:

embedderesource

Take care, that if you have debugged the app before, you must uninstall it to make  disappear the file from Assets/Data.

The following methods makes really easy change from content to embedded resource.

public static Stream LoadEmbeddedStreamAsync(Type type, string contenturi)
{
    var assembly = type.GetTypeInfo().Assembly;
    var relativepath = ConvertContentEmbedded(contenturi);
    var embeddedpath = $"{type.Namespace}.{relativepath}";

    var stream = assembly.GetManifestResourceStream(embeddedpath);

    return stream;
}

public static async Task<string> LoadEmbeddedTextFileAsync(Type type, string contenturi)
{
    var stream = LoadEmbeddedStreamAsync(type, contenturi);

    return await ReadStringFromStreamAsync(stream);
}

What really means setting the file as embedded resource?

For one side we have added another entry to the resources.pri file (in case the file is in the project, in case is in a library it will be called [libraryname].pri.

To take a look to the file, just get the XML with the following VS tool:

pridecoder2

And not just open it and find the entry of the file:

resourceentry.JPG

Aside: If you install a UWP SDK like the 15003 prerelease, this and other tools are unique, that means that you won’t be able to upload an appx, because this tool ‘makepri’ is not a released version, you will have to uninstall both SDKs, and install again the latest released one.

If I understand it right, the file is embedded in the executable, so in theory is really protected, taking a look to it, we see the change in the size:

executables

We can check that easily adding an Image and setting it like a embedded resource:

addedimage

It is clear where the file is embedded now. Now we understand we should not add big files in here because it will make increase the executable and decrease time loading and performance.

But what about adding it inside a UWP library?

Big Files

In this case, I am going to add an image inside a assets library and try to show in a Image Control.

To make things easier, create a class in the UWP library called Library and the project AssetsLibrary and also let’s add a file inside Images:

assetslibrary

Now set the image as embedded resource and call it from the code behind of a page:

private async void Initialize()
{
    var stream = ResourceFilesService.LoadEmbeddedStreamAsync(typeof(Library),"ms-appx:///Images/spacebackground.jpg");

    var bitmapimage = new BitmapImage();

    BackgroundImage.Source = bitmapimage;

    await bitmapimage.SetSourceAsync(stream.AsRandomAccessStream());
}

Perfect the image is shown in the BackgroundImage control. So now you can implement behaviors or static methods for compiled binding to set the images you want to protect.

Big files to the local folder

Finally in case you need to copy a file from an embedded resource to the local folder, follow these steps:

public static async Task CopyResourceToLocal(Type type, string resourcepath, string filename)
{
    var localFolder = ApplicationData.Current.LocalFolder;
    var dbFile = await localFolder.TryGetItemAsync(filename) as StorageFile;

    if (null == dbFile)
    {
        var stream = LoadEmbeddedStreamAsync(type, resourcepath);

        //Copy the stream
        var storageFile = await localFolder.CreateFileAsync(filename);

        using (var outputStream = await storageFile.OpenStreamForWriteAsync())
        {
            await stream.CopyToAsync(outputStream);
        }
    }
}

For instance

 await ResourceFilesService.CopyResourceToLocal(typeof(Library),"ms-appx:///Data/Resource.txt","Local.txt");

And that’s all hope with this information, you can keep your app more robust avoiding possible user mistakes.

Download the ResourcesFileManager.cs

Take a look all I create about #UWP #Windows10 at @juanpaexpedite

Analyzing Paint 3D 1/2

Until we have the new Windows 10 Creators Update and the new SDKs, APIs, etc. I need few days to relax my mind from creating my new Universal app Games Time Machine. I learn a lot about performance, SQLite with EF7 and UI new ways. I encourage you to grab it at Games Time Machine at the W10 Store and ask me about any part you are interested, I will glad to address on how to solve an issue or how to make it work any you need.

Now after following the twitter from @justinxinliu I decided to analyze Paint 3D, in theory the most next Creators Update App style.

Attaching

The first step is launch Paint 3D and now launch VS2017 (might be with 2015 works but you know is 2 years old now 🐱🐉 ), and attach in the following way:

first

Now search for Paint and attach in Native mode:

second

And here we go, now we can analyze several interesting parts of the app.

App Manifest

Just a quick view of what is interesting inside:

appx

As you can see there is a Device called Windows.Team (no idea what can be). and an internal SDK 14800.

From the Uri rules, look like the codename was Denali which is a protected website:

urirules

Layout

layout

The app contains:

  1. Grid with TopBar, SideBar, CommunityDiscoveryPanel, ContextSideBar, Grid, Rectangle, HamburgerMenu and a DebugMenu.
  2. A ContentControl binded to the StartViewModel.StartVM, might be a trigger to begin some kind of actions.
  3. The AboutBox, it is interesting because it’s full size, with a Brush Transparent (to lock all the elements behind). An small bug it has is that should block the key or the controls behind when the AboutBox is shown, but it’s not, you can press tab and cycle control focus and activate them. Hope in new releases they give an easier option to lock what is behind.paintfocus.JPG
  4. The HsvColorPicker, which I will analyze later.
  5. A Loading overlay, which must be like a MessageDialog (CancelCoomand, Description, Image, IsOpen, Title)
  6. A Change Text Overlay similar to the previous one, (CancelCommand, OkCommand, Text)
  7. A grid that contains the WebBlendControl, yes web. I will take a look to it later.

Top Bar

This bar if 50 Height, not 48, so is not now a x4 factor, the background color is #FF363941. I should try referencing an static resource to know if this value is hard coded or referenced.

topbar

It contains three parts, The hamburger, which is an ActionableCheckBox, a ResponsivePanel to change the ExpandedView and the CompressedView, and another Grid on the right for the Actions and Remix3D.

  1. The Hamburger ActionableCheckBox is 66×50 with minSize 66×50 and it comes from the style of Checkbox.it contains and IsAction Property to change if the Menu is Open or not.
  2. The Responsive Panel (in expanded view) [I do not know if it is possible to analyze the Visual States]. To summarize is like an ItemsPanel with ItemsSource and SelectedItem. The ItemContainerStyle sets the size to 66×50 of each item.
    1. Each item is a SimpleSelectorItem that changes the visibility of a grid when selected or unselected, the only difference is a linearbackgroundbrush I will detail later.
  3. And finally on the right a non named panel, a bit less organize with a 66×66 button, yes is bigger, why? and also the other buttons are 66×66.

Side Bar

sidebar

This bar contains a lot of controls inside, let’s analyze how are organize (hardcoded or with binding) and what kind of controls are. All inner panels are of type ResponsivePanel that changed from ExpandedView to CompressedView depending on the Window size.

It has two parts, the tool section, and the colors below. Let’s begin with the low part, the color selector, the container is a grid of 264W and inside it is an stack panel. The most interesting part is the colors section. It is a RelativePanel with a WrapPanel with all the Colors of type ColourThumb.

colorborder

It changes the Visibility of the Grid, the over has -2 of margin and 2 of Border Thickness to make the effect of grow.

Now let’s analyze the tools section. each tool item is a canvas with several paths inside, might be in the future we see SVG items here.

Interaction

In summary after digging in the visual tree, it’s a SwapChainPanel (HighFrecuencyInputPanel) , I will have to take a look if it’s the same like the InkCanvas.

Bottom Bar

This contains ZoomScale Buttons and buttons to change the view to edit or view.

Now we have analyzed the layout and itemsizes, let’s continue with the Icons used and fonts.

Icons & Fonts

One of the firsts parts I always take a look is the fonts and the symbols what are they done, pixel, paths, fonts, etc.

Let’s analyze the Top Bar:

The Hamburguer button is of type ActionableCheckBox, the content is an Icon with HamburgerIcon which is slightly different from the Seoe MDL2 Assets.

Now the middle top panel is of type PaintStudio..ResponsivePanel with popup values, Each button inside, is a PaintStudio..SimpleSelectorItem and the content is using this font Assets/Fonts/PaintA.ttf#paint and the chars are B, ~, and so on, so apparently are not a new Segoe Creators Update Font.

Let’s see if we can achieve that font. The app is installed in a place like:

C:\Program Files\WindowsApps\Microsoft.MSPaint_1.1612.14017.0_x64__8wekyb3d8bbwe

And here we can see inside the Assets Folder three fonts: Icons.ttf, BhaiMDL2.1.84.ttf and PaintA.ttf

Icons

This font contains the following information:

fontinfo

Generated by IcoMoon, interesting, isn’t it?. And it just contains 3 characters:

fontchars

Beihai MDL

This name looks like the Creators Update internal name, later I will explain why. This second one is from Microsoft and is an small subset from Segoe MDL2 Assets:

secondfont

As you can see in the screenshot, containing the whole collection, it contains a new facebook and twitter symbols which, I think are not in Segoe MDL2  Assets.

Paint

Now let’s take a look to the PaintA.ttf

paintfont

All the screenshots were using my app Universal Character Map . except the first one, using FontForge desktop app (great for editing fonts). As you can see here is where includes a Hamburger symbol. I do not understand why is not the same from Segoe, might be in the Creators Update all will be reorganized. Also all the icons included in the Hamburger menu were done using this font.

For the rest of the menu items, all are custom controls. Hope they are included by default or in templates to stylish new apps.

Colors & Gradients

All the menus, all the icons, etc. have the following gradient:

gradient

It looks like the colors do not belong to an Style (static resource) but might be included in the future for default styles in UWP apps.

In the following post, I will analyze the controls, all the coloring and shadows, and I will try to dig about visualstates and animations if it’s possible. Meanwhile the other laptop is to 15014, I will check if there is any new version of Paint3D or any other app to analyze.

Regards @juanpaexpedite

 

Compiled binding,Page Resources and Visual States

I have tried to find the cleanest way in terms of reusability, less code repeating, functionality, etc. And after plenty of experiments the following is the one I consider more interesting. First I explain how to use directly from the page, and after from a datatemplate.

Page Resources

When we define a double in XAML like a resource, you will be able to use as a resource just once, also you will able to change on runtime using the VisualStateTriggers, but the Controls referenced to it won’t get the updates, because we only have StaticResources in UWP and no DynamicResources. Also a x:Double cannot have a Name in the Page Resources Section.

Having this in mind, you can define tons of dependency properties in your XAML Page code behind and bind it but makes the code less clean. So what can we do, let’s create XAML Properties.

To begin let’s define the DoubleProperty which represents a double in the XAML world, that means a DependencyObject:

public class DoubleProperty : DependencyObject
    {
        public double Value
        {
            get { return (double)GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }

        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register(nameof(Value), typeof(double), typeof(DoubleProperty),
                new PropertyMetadata(DependencyProperty.UnsetValue));
    }

Now we can use it as a real resource because now can have a name in the Page Resources.

<Page.Resources>
        <c:DoubleProperty x:Name="HeaderFontSize" x:Key="HeaderFontSize" Value="24.0"/>
        <c:DoubleProperty x:Name="DescriptionFontSize" x:Key="DescriptionFontSize" Value="14.0"/>
</Page.Resources>

Compiled binding

Now in case we want to create a TextBlock with one of the defined font sizes:


<TextBlock Text="Sections"  FontSize="{x:Bind HeaderFontSize.Value, Mode=OneWay}" />

Visual States

And now let’s create the Visual States Section

<VisualStateManager.VisualStateGroups>
    <VisualStateGroup x:Name="VisualStates" >
        <VisualState x:Name="Full">
            <VisualState.StateTriggers>
                <AdaptiveTrigger MinWindowWidth="600" />
            </VisualState.StateTriggers>
        </VisualState>
        <VisualState x:Name="Small">
            <VisualState.StateTriggers>
                <AdaptiveTrigger MinWindowWidth="0" />
            </VisualState.StateTriggers>
            <VisualState.Setters>
                <Setter Target="DescriptionFontSize.Value" Value="12"/>
                <Setter Target="HeaderFontSize.Value" Value="18"/>
            </VisualState.Setters>
        </VisualState>
    </VisualStateGroup>
</VisualStateManager.VisualStateGroups>

Where we can easily change the values because this resources have x:Name. Now when you run the app you will see how it adapts the fontsize according to the Windows Width.

Now, the WOW part, at least IMHO, because there is not an official way to do it at the moment.

Data Templates

First we need to define a Current static property of the Page in the constructor, it is the only code behind you need:

public static HomeView Current { get; set; }
public HomeView()
{
    Current = this;
    this.InitializeComponent();
}

Now we can bind to it from a DataTemplate for instance:

<DataTemplate x:Key="SampleDataTemplate" x:DataType="m:SectionInfo">
   <Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="240"/>
    </Grid.RowDefinitions>
    <TextBlock Text="{x:Bind Name, Mode=OneWay}" FontSize="{x:Bind local:HomeView.Current.HeaderFontSize.Value, Mode=OneWay}"  />
    <TextBlock Grid.Row="1" Text="{x:Bind Description, Mode=OneWay}" FontSize="{x:Bind local:HomeView.Current.DescriptionFontSize.Value, Mode=OneWay}" />
   </Grid>
</DataTemplate>

So now with this we can bind double values and get their updates on the go, and if we have values, can we have any other type. Why not a generic object, let’s continue defining GeneryProperty:

public class GenericProperty : DependencyObject
{
    public object Value
    {
        get { return (object)GetValue(ValueProperty); }
        set { SetValue(ValueProperty, value); }
    }

    public static readonly DependencyProperty ValueProperty =
        DependencyProperty.Register(nameof(Value), typeof(object), typeof(GenericProperty), 
            new PropertyMetadata(DependencyProperty.UnsetValue));
}

In the page resources section let’s add a Brush:

<c:GenericProperty x:Name="CustomColor" x:Key="CustomColor">
    <c:GenericProperty.Value>
      <SolidColorBrush Color="Blue"/>
   </c:GenericProperty.Value>
</c:GenericProperty>

And in the Visual States Section:

<VisualStateManager.VisualStateGroups>
    <VisualStateGroup x:Name="VisualStates" >
        <VisualState x:Name="Full">
            <VisualState.StateTriggers>
                <AdaptiveTrigger MinWindowWidth="600" />
            </VisualState.StateTriggers>
                </VisualState>
                <VisualState x:Name="Small">
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="0" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Target="DescriptionFontSize.Value" Value="12"/>
                        <Setter Target="HeaderFontSize.Value" Value="18"/>
                        <Setter Target="CustomColor.Value">
                            <Setter.Value>
                                <SolidColorBrush Color="Orange"/>
                            </Setter.Value>
                        </Setter>
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
</VisualStateManager.VisualStateGroups>

And finally, having casting in compiled binding, we can do the following:

<Grid  Background="{x:Bind (Brush)local:HomeView.Current.CustomColor.Value, Mode=OneWay}" >
...
</Grid>

I have tested this with the latest insider release 14905, I understand it works from the Anniversary Update.

Conclusions

This is just the beginning, now we have methods and casting, we can make practically everything directly from XAML just adding that Current property. I think this article solves plenty of questions about DynamicResources, how to bind a resource, etc.

You can get the source here CompiledBindingExamples

Hope you find it useful and as always follow me at @juanpaexpedite to know interesting UWP stuff. Now I am preparing a new dev oriented App I hope finish it in few weeks.

Images in Composition

I am developing my apps with more visual transitions, animations, etc. all managed in the Visual Layer, is really smoother than using XAML animations, there are no dependency properties and might be, you remember that animating some properties were not optimized.

To clarify adding images in Composition let’s explain the example I am achieving.

In my case I want to fade from Image to another Image, when I began to do this I uses the ArithmeticCompositeEffect with the following definition:

var effectDef = new ArithmeticCompositeEffect
            {
                Name = "effect",
                ClampOutput = false,
                MultiplyAmount = 0,
                Source1Amount = 1,
                Source2Amount = 0,
                Source1 = new CompositionEffectSourceParameter("ImageSource"),
                Source2 = new CompositionEffectSourceParameter("Source2")
            };

And it works really well like in the ‘Finding Dory’ tweets I did. So I decided to follow that way, when is showing one of the Images I could update the other one with other Uri/File source and animate again. But it makes a disgusting flickering I think you cannot avoid.

The only way to do this is extracting the base of the CompositionImage class from the SamplesCommon project and set two SpriteVisuals in a ContainerVisual and animate the Opacity of each.

So I decided to make a diagram of all the flow in there, to understand what is happening, because meanwhile the Composition API is final, it has been changing the way of the Images and other sources are obtained.

In this case I want to set an Image in the Visual of a custom class that inherits from control:

composition

The steps to set a Visual in the Element are the following were you will need the SamplesCommon source project reference:

  1. Gain access to the Visual Layer (Composition) by calling the GetElementVisual of static ElementCompositionPreview.
  2. From the compositor of the Visual create an SpriteVisual and a SurfaceBrush.
    1. The SpriteVisual will be the Child of the Control Visual.
    2. The SurfaceBrush will be brush that fills the SpriteVisual (like ImageBrush in the Background of a Grid in XAML)
  3. Create a CompositionDrawingSurface using SurfaceLoader Helper
  4. Set that surface to the SurfaceBrush previously created.
  5. Set the SurfaceBrush as Brush of the SpriteVisual.
  6. Set the Child Visual of the Visual by calling SetChildElementVisual of the static ElementCompositionPreview.

It might appear a bit complex, but what it really means is you have a lot of control of what to do. For instance (I have not tried it yet) you have access to a DrawingSession that means you can make a lot of geometric and drawing operations in that step, might be even use Win2D effects (I have to check that and also if is a transparent session)

This Surface ‘Image’ brush of the SpriteVisual is one of you can set, you can take a look more options in here: https://msdn.microsoft.com/en-us/windows/uwp/graphics/composition-brushes.

Also you have now the composition properties of the Visual and the ‘Child’ SpriteVisual and you can animate all of them smooth, which is really important.

And the SurfaceBrush has properties like the XAML ImageBrush like alignments, stretch, etc. which make the things easier to work with.

Hope this makes easier to understand the flow of the Visual Layer and how interoperates with Win2D objects. As always @juanpaexpedite