Bonobo Git Server and Visual Studio 2015

bonobo

EN: I always wanted to create a private Git repository and after test my first commit from Visual Studio here I attach a guide I hope make it an easy walkthrough to configure it: gitlocal_en

ES: Siempre he querido crear un repositorio privado de Git y después de mi primer commit con el desde Visual Studio adjunto aquí una guía que espero que te haga el camino más fácil para configurarlo.gitlocal_sp

Win2D Particles

One of the apps I am preparing has a particles adornment, I made the first version ‘solve version’ and now I have implemented the ‘code version’.

deer

The CanvasAnimatedControl

This Win2D Control is like having XNA in UWP apps, you can subscribe the following events:

private void Initialize()
{
    MainCanvas.CreateResources += MainCanvas_CreateResources;
    MainCanvas.SizeChanged += MainCanvas_SizeChanged;
    MainCanvas.Update += MainCanvas_Update;
    MainCanvas.Draw += MainCanvas_Draw;
}

Where CreateResources is where you generate and download all the source images you will need in the other events. SizeChanged is just the base event to keep the bounds, Update is when you modify the position and effect of the particles, and finally the Draw event when you paint each particle in the control.

Particles Generator

Basically it has the following structure:

  1. Create the textures (small circles with blur)
  2. Create a List of particles at different positions.
  3. Add displacement with turbulente effect per particle. (turbulence gives more natural effect)
  4. Update Turbulence

And then draw the result each time.

Creating the Textures

In order to use only Win2D, I created 4 bitmaps (CanvasRenderTarget) of different sizes with a chained painting session where:

  1. Paint two circles in a canvas
  2. Apply blur effect to the previous canvas.
using (CanvasDrawingSession targetSession = canvas.CreateDrawingSession())
{
    targetSession.Clear(transparent);
    targetSession.FillCircle(center, nextRadius, outerColor);
    targetSession.FillCircle(center, nextRadius - 6, innerColor);
}
var blurEffect = new GaussianBlurEffect() { BlurAmount = 2f };
CanvasRenderTarget blurredcanvas = new CanvasRenderTarget(device, viewportsize, viewportsize, parent.Dpi);
blurEffect.Source = canvas;
using (CanvasDrawingSession targetSession = blurredcanvas.CreateDrawingSession())
{
    targetSession.Clear(transparent);
    targetSession.DrawImage(blurEffect);
}

Each of these bitmaps will be used as sources of every particle drawing, which has a displacement with turbulence effect, when you apply this effect you must create a big viewport, 100 px in this case, because is drawn the original image and the displacement image, so to avoid this just create this safety viewport.

Decrease ‘float viewportsize = 100;’ if you want to watch the weird result.

Creating the Particles

Now we have the images let’s create the particles, you have to consider the window bounds and the size changes. I added a random orientation for each particle and if you want only falling particles:

public void CreateParticles(bool fall)
{
    particles = new List<Particle>();

    int i = -1;
    int minpos = minRadius * sizes * 2;
    while (++i < amountparticles)
    {
        var x = generator.Next(minpos, (int)bounds.Width);
        var y = generator.Next(minpos, (int)bounds.Height);
        var s = generator.Next(0, sizes);
        var ox = generator.NextDouble() > 0.5 ? 1 : -1;
        var oy = fall ? 1 : generator.NextDouble() > 0.5 ? 1 : -1;

        var particle = new Particle(x, y,s,ox,oy, particleBitmaps[s], particlefall:fall);
        particles.Add(particle);
    }
}

As you see is just creating a list with random values for each property. In the constructor of each particle I add the effects.

Displacement with turbulence

random = generator.Next(2, 50);
factor = 0.7f * random / 10.0f;
var octaves = generator.Next(1, 5);
turbulence = new Transform2DEffect() { Source = new TurbulenceEffect() { Octaves = octaves } };
displacement = new DisplacementMapEffect() { Source = source, Displacement = turbulence };

The idea of the displacement is to displace and deform the particle according to the turbulence effect. If you want to see what is the turbulence, in the drawing session, draw the turbulence effect instead the displacement.

Update the turbulence

Now we have the turbulence created we have to move the particle around it is position using the following turbulence which also deforms the particle:

private void UpdateTurbulence(float elapsedTime)
{
    TurbulenceMatrix = Matrix3x2.CreateTranslation((float)Math.Cos(elapsedTime + random) * 2 - 2, (float)Math.Sin(elapsedTime) * 2 - 2);
    turbulence.TransformMatrix = TurbulenceMatrix;
    displacement.Amount = (float)Math.Sin(elapsedTime * factor) * random;
}

It is relative simple to create this environment, I have to recognize that in my 1320 goes slow, but in desktop works really well, I cannot assure is because the displacement effect, might be reducing the update times could be great so I let you go and test it.

I hope you enjoy the article and take the idea about how to create images/textures in Win2D and then apply to a CanvasAnimatedControl like in the XNA old ages so simplifies the code a lot.

And as always you have the code in the Particles2D project of my repo : Github

Follow me to know the latest code about Windows10 @juanpaexpedite

‘Remember Build 2015’ Composition Example

I decided before continuing with my apps to dig more into Composition and make some kind of clean layout to make some experiments with Composition API.

Sooner than later will be the next Build and I usually rewatch cool videos from it so I decided to make this example around the 2015 edition.

build2015

gallery

sessions

In this case I set the Composition animations in another library to begin having it ready for an app. The animations that are called to my previous demo (id software demo) are NOT equals so please be careful about this.

One important thing I wanted in an app is the idea to change the focus visually so I make the things appear at different times and I consider that the implementation looks great!

NOTE1: I have added waits in some of the attached properties, might be more solid code if the logic is in the loaded event, in order to have all the attached properties on time including the binding, because in this example I had to set in order from left to right the attached properties to had them when is needed!

NOTE2: I use attached properties because are inline and visually more clean, that makes if you need to read more properties before act a bit more complex so if you consider you can use behaviors too.

It is recommended to run the app without debugging to watch all times right!!

Properties

In this example we have the following Attached Properties:

DoubleEffectParameter, BoolEffectParameter

These are generic attached properties to use joined with other attached properties to adjust the values of the other properties.

Delay

Use it in conjunction with an Effect Property to make transitions one before another is in seconds of double.

FadeOut

Allows a control go from Composition Opacity 0 to one using the previous parameters, as example:

<Grid Background="{StaticResource GradientSky}" a:Effects.DoubleEffectParameter="10"  a:Effects.FadeOut="True" />

Appear

It makes an offset and opacity appearing effect animation at the same time.

<Grid Width="1600" a:Effects.Delay="3.5" a:Effects.DoubleEffectParameter="2" a:Effects.Appear="True" HorizontalAlignment="Left" IsHitTestVisible="False"/>

Disappear

It takes the height of an element and animates it until disappears to the top.

<StackPanel  a:Effects.Delay="1" a:Effects.BoolEffectParameter="False" a:Effects.Disappear="True"/>

Blend

It is a cool one that makes a transition among images, I use it in the example for the gallery, move the mouse around images and it will make a transition. Being GalleryImage a Grid:

GalleryImage.SetValue(Effects.BlendForegroundProperty, newuri);

I have not tested by using binding to a property, theorically should work.

Column

columns

In this case the Column Attached Property makes the appear effect begin when the scrollviewer arrives to the column value position.

Parallax

You need to specify which is one the scroller to get its Composition Layer and then the factor of parallax you want to apply. The effect is interesting because shows that you are scrolling even when the main content has not appear (eg. column 1 appearing).

Easy to use as the following example:

<Image x:Name="Background0"  a:Effects.ElementParameter="{Binding ElementName=Scroller}" a:Effects.Parallax="0.2"/ 

NOTE: I wanted to create a color Composition transition from blue to orange, that’s why exists Gradient but at this moment it has to be with Win2D, so to focus in Composition I omitted it.

Animating Scrolling

I did not test this feature until this example and works great, the idea is emulate a Pivot or a Hub Control with just simply a scrollviewer and grids, you can do it by using:

  #region Scroller
        private void Scroll()
        {
            Scroller.ChangeView(screenWidth * currentgrid, null, null);
        }
        #endregion

        #region Button Events
        private void InitializeEvents()
        {
            FirstButton.Tapped += ScrollButton_Tapped;
            SecondButton.Tapped += ScrollButton_Tapped;
            ThirdButton.Tapped += ScrollButton_Tapped;
        }

        int currentgrid = 0;
        private void ScrollButton_Tapped(object sender, TappedRoutedEventArgs e)
        {
            if (sender.Equals(FirstButton))
                currentgrid = 1;
            else if (sender.Equals(SecondButton))
                currentgrid = 2;
            else if (sender.Equals(ThirdButton))
                currentgrid = 3;
            Scroll();
        }

NOTE: If you can you can hide the bar and lock the scroll, it makes the scroll method still working so it is a really interesting option!

Behaviors

I tested the tilt effect behavior from r2d2rigo and works cool! so I decided to use it in the example for the list.

Html Processing

If you never have processed html using htmlagilitypack, this is a good example, might be there is a better thing to extract values from attributes, if you know it, would you give me a clue?

Issues

I have some odd behaviors that I want to comment

  • I had to force a height in the ItemsControl of the sessions because the margin was impossible to force to make it a relative height.
  • Because something odd between Github and Nuget the code I had to use of HtmlAgilityPack is not perfect, there are methods that do not appear to me.
  • The Scroll method works pretty well except sometimes when go again to HorizontalOffset Zero, but I understand might be a bug.

And finally the source code:
Composition Examples inside the Parallax Project Folder

Hope enjoy @juanpaexpedite

Search Groove in Composition Example

Composition API has really great features and with the new examples is even better.

bowie

If you take a look to the ContinuitySample, you will learn how to get a Visual that will still in screen when the app navigates in a Frame, which was a doubt I had and I was to test in few days, so thank you Composition team to make it quicker than us:).

And Parallax Music example has really cool scrollviewer effect which is the one where I want to add some code to find artist IDs.

Of course is not the main purpose of the Composition example but cause they give us the chance to play with Groove let’s add the search option.

After you tested the that example with your id add the following:

IDatasource.cs

//At the end of the interface add this method declaration
    Task SearchArtistId(string name);

RemoteDataSource.cs

//At the end of the class
#region Search
private static readonly string SEARCH = "music/search?q=";

private async Task Search(string query)
{
    var service = SERVICE + "/" + SEARCH + query + "&accessToken=Bearer+" + WebUtility.UrlEncode(Token);
    var response = await _client.GetAsync(new Uri(service));
    var content = await response.Content.ReadAsStringAsync();
    return content;
}

public async Task SearchArtistId(string name)
{
    var content = await Search(name);
    if (content != null)
    {
        JsonObject jsonObject = JsonObject.Parse(content);
        var _artist = jsonObject["Artists"].GetObject()["Items"].GetArray()[0].GetObject();
        return _artist["Id"].GetString();
    }
    return null;
}
#endregion

Now we have the implementation, let’s add the XAML and events.

MainPage.xaml

Before the ProgressRing add:

<!--#region Added for look up-->
<StackPanel Orientation="Horizontal" RelativePanel.AlignRightWithPanel="True" RelativePanel.AlignTopWithPanel="True">
    <TextBox x:Name="SearchBox" Width="320"/>
    <Button x:Name="SearchButton" >
        <SymbolIcon Symbol="Find" />
    </Button>
</StackPanel>
<!--#endregion-->

MainPage.xaml.cs

Remove readonly for DEFAULT_ARTIST_ID and now add the following:

public MainPage()
{
    this.InitializeComponent();

    this.InitializeSearch();
    ...
}

#region Search
private void InitializeSearch()
{
    SearchButton.Tapped += async (s, e) =>
    {
        var text = SearchBox.Text;
        if (!String.IsNullOrEmpty(text) && text.Length > 2)
        {
            var result = await _dataSource.SearchArtistId(text);
            DEFAULT_ARTIST_ID = result;
            InitializeData();
        }
    };
}
#endregion

Piece of cake, isn’t it?. I’ve never used Groove and works really efficient. The following I post will be some examples of Composition that I want to make for some of my controls.

Regards @juanpaexpedite

XAML Attached Properties Composition Effects

Hello, today I made my first XAML step with Composition. This is the XAML result after making alchemy with XAML, Composition and the Win2D effects.

saturation1

The idea is to create Effect attachable properties to add for instance a saturated background that can even follow binding saturation changes and size changes.

beach

Prerequisites

– I did not find any NuGet of the Microsoft.UI.Composition.Toolkit, so I copy it from the composition-master from the Microsoft Windows Composition repository, you should download it and reference for the project.
– Learn a bit about Effects, just their properties and what they do, you can take a look to the official documentation and in my ‘old’ Win2D posts:
Win2d Posts
– Know what are attached properties and how to implement that in XAML.
– Know what are dependency properties and how to add to a dependency object and user them in XAML.

Common code for composition

If you know a bit of the prerequisites, now you need how to get the visual layer from a UIElement, the compositior and how to create the CompositionImageFactory. All of these are required to manipulate the visual layer:

public class CompositionManager
{
    public static ContainerVisual GetVisual(UIElement element)
    {
        var hostVisual = ElementCompositionPreview.GetElementVisual(element);
        ContainerVisual root = hostVisual.Compositor.CreateContainerVisual();
        ElementCompositionPreview.SetElementChildVisual(element, root);
        return root;
    }

    public static Compositor GetCompositor(Visual visual)
    {
        return visual.Compositor;
    }

    public static CompositionImageFactory CreateCompositionImageFactory(Compositor compositor)
    {
        return CompositionImageFactory.CreateCompositionImageFactory(compositor);
    }
}

Saturation class

Now we know how to gain access to the visual layer, let’s create a Dependency object class called Saturation that will have the following fields and properties:

Element

Is the attached element for the Saturation class

#region Element
private UIElement element;
private FrameworkElement frameworkElement;
#endregion

Source

Is the dependency property that will take as Image Source for our Saturation Effect

#region Source
public string Source
{
    get { return (string)GetValue(SourceProperty); }
    set { SetValue(SourceProperty, value); }
}
public static readonly DependencyProperty SourceProperty =
    DependencyProperty.Register(nameof(Source), typeof(string), typeof(Saturation), 
		new PropertyMetadata(null));
#endregion

Composition

We need to get the Visual Composition layer of the Element:

Image from blog.windows.com

#region Composition
private ContainerVisual visual;
private Compositor compositor;
private CompositionImageFactory imageFactory;
#endregion

Variable Effect

We want to change the value of the Saturation in the Saturation Effect, to make that, we need to set the Saturation as ‘animatable’. We have to set a name for the SaturationEffect and know the path of the Saturation (like when we use Storyboards).

#region Effect
private string EffectSource = "EffectSource";
private string SaturationEffect = "SaturationEffect";
private string SaturationEffectPath = "SaturationEffect.Saturation";
private SaturationEffect effect;
private CompositionEffectFactory effectFactory;
#endregion

Composition Brush and Image

This is the image we will create

#region CompositionImage
private CompositionSurfaceBrush surfaceBrush;
private CompositionImage imageSource;
#endregion

What we paint on the composition image

We have to create the image with the effect using the following:

#region Brush & Sprite
private CompositionEffectBrush effectBrush;
private SpriteVisual spriteVisual;
#endregion

Some of these fields might sound a bit confusing, but I made the methods simple and step by step to make things clear.

Initialization

When the attached property sets (I will explain later) we will call to this method.

public void Initialize(UIElement attachedelement)
{
    element = attachedelement;
    frameworkElement = element as FrameworkElement;
    CreateImageFactory(element);
    CreateEffect();
    CreateSurface();
    CreateBrush();
    CreateSpriteVisual();
    Insert();
    DetectElementChange();
}

Where CreateImageFactory is an standard method to get the visual, compositor and create an imageFactory to work:

using static Universal.Managers.CompositionManager;

private void CreateImageFactory(UIElement element)
{
    visual = GetVisual(element);
    compositor = GetCompositor(visual);
    imageFactory = CreateCompositionImageFactory(compositor);
}

To make code more readable the CompositionManager class that is common to for any effect you need I added as static.

Creating the Effect

This step is important to understand:

  • To create an effect that can change a property during the runtime, we need to assign to the Effect a name.
  • To add a source to the effect that comes from composition instead from Win2D we assign a CompositionEffectSourceParameter
  • Update Level is the value that converts percentage to 0.0 to 1.0f values and sets to the animatable property.
  • Effect Factory creates the effect with the path defined before to allow us to change the saturation level.
private void CreateEffect()
{
    effect = new SaturationEffect()
    {
        Name = SaturationEffect,
        Saturation = 0.0f,
        Source = new CompositionEffectSourceParameter(EffectSource)
    };

    UpdateLevel();
    effectFactory = compositor.CreateEffectFactory(effect, new[] { SaturationEffectPath });
}

(UpdateLevel method is explained later).

Surface, Brush and SpriteVisual

private void CreateSurface()
{
    surfaceBrush = compositor.CreateSurfaceBrush();
    var uriSource = UriManager.GetFilUriFromString(Source);
    imageSource = imageFactory.CreateImageFromUri(uriSource);
    surfaceBrush.Surface = imageSource.Surface;
}

private void CreateBrush()
{
    effectBrush = effectFactory.CreateBrush();
    effectBrush.SetSourceParameter(EffectSource, surfaceBrush);
    effectBrush.Properties.InsertScalar(SaturationEffectPath, 0f);
}

private void CreateSpriteVisual()
{
    spriteVisual = compositor.CreateSpriteVisual();
    spriteVisual.Brush = effectBrush;
    spriteVisual.Size = new Vector2(GetElementWidth(), GetElementHeight());
}

Where GetElementWidth and GetElementHeight are safe methods to avoid NaN from the Element values.

Level of Saturation

The Level dependency property:

#region Level
public double Level
{
    get { return (double)GetValue(LevelProperty); }
    set { SetValue(LevelProperty, value); }
}

public static readonly DependencyProperty LevelProperty =
    DependencyProperty.Register(nameof(Level), typeof(double), typeof(Saturation), new PropertyMetadata(0.0, LevelChanged));

private static void LevelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    (d as Saturation).UpdateLevel();
}

private void UpdateLevel()
{
    if (effectBrush != null)
    {
        var newvalue = (float)(Level / 100.0);
        effectBrush.Properties.InsertScalar(SaturationEffectPath, newvalue);
    }
}
#endregion

Insert the composition created and detect size changes

Finally let’s add the composition to the Element in its visual layer and detect its size changes:

private void Insert()
{
    visual.Children.InsertAtBottom(spriteVisual);
}

private void DetectElementChange()
{
    frameworkElement.SizeChanged += (s, e) =>
    {
        UpdateSpriteVisual();
    };
}

Conclusions

Composition allows to change parameters and follow size changes without recreating all the image, effect, etc. which makes the interface more responsive and efficient.
It is similar to animate/change an effect value as it is were a Storyboard.
The image source of an effect is using CompositionEffectSourceParameter.
You have to get the visual layer from an UIElement using the methods in the CompositionManager.

Source code

The source code is available on GitHub in the UniversalExamples-SaturationEffectPage

It is my first step in Composition, in following articles I will take a look how to add more effects, animate plenty of equal instances and many more.

To be up to date @juanpaexpedite and happy coding.

IoT Vector pack

IoTVectorpack_post

I decided to gift my IoT vector pack to be used in any IoT app, I made with the great Inkscape, rename from .doc to .svg  IoTVectorpack .

If you want to learn how to use to clip a control all the information here:

Sensing world with Windows 10 IoT screenshot.jpg

In the link I created a document that explains in details all the steps even how to make the clipping to show the level of a sensor in a range.

Let’s improve the IoT designs:).

As always get all my latest at

Advanced Flyouts for UWP (Windows 10)

Suppose you are adding a button for searching in a ‘command bar’ and you want to create a flyout that contains a textbox and a gridview like the following:

wordpress.png

The usual step is to fill the property Flyout of the Button search with a Flyout, but this makes two issues in this case:

  1. If you want to show a child flyout with a context menu as shown, instead of appearing, both parent and child disappears.
  2. In Mobile when you have the virtual keyboard and a flyout, after losing the focus of the virtual keyboard, the whole flyout disappears.

In order to solve both issues, we need to understand what is really a Flyout and see how to implement our solution.

Analysis

To begin, let’s use the standard Flyout:

<Button.Flyout>
    <Flyout >
        <ContentPresenter ContentTemplate="{StaticResource SearchTemplate}"/>
    </Flyout>
</Button.Flyout>

Where SearchTemplate has the following structure:

<DataTemplate x:Key="SearchTemplate">
     <Grid Height="320" Width="320" >
         <Grid.RowDefinitions>
             <RowDefinition Height="Auto"/>
             <RowDefinition Height="1*"/>
         </Grid.RowDefinitions>
         <TextBox ></TextBox>
         <GridView  Grid.Row="1">
         </GridView>
     </Grid>
 </DataTemplate>

Now let’s create a method to analyze what happens when an item of the gridview is right tapped:

private void Child_RightTapped(object sender, RightTappedRoutedEventArgs e)
{
    var current = (FrameworkElement)sender;
    var parent = (FrameworkElement)VisualTreeHelper.GetParent(current);
    while (parent != null)
    {
        current = parent;
        parent = (FrameworkElement)VisualTreeHelper.GetParent(current);
    }
}

When this event is fired, we get as result that current is a Canvas, because a Flyout has no self representation, it is a Popup that has as child a FlyoutPresenter, to clarify:

var popupContainer = current as Canvas;
var popup = popupContainer.Children.First() as Popup;
var flyoutpresenter = popup.Child as FlyoutPresenter;

If we call:

var openpopups = VisualTreeHelper.GetOpenPopups(Window.Current);

It will confirm that we have one Popup which is the same of the Flyout. That means that we will have to create a new Flyout class that creates a Popup, but before that let’s analyze if we want to show a child Flyout inside the parent Flyout.

Child Flyout

Suppose we have the following itemtemplate for the items of the GridView inside the Parent Flyout:

<StackPanel Orientation="Vertical" Tapped="Child_Tapped" Holding="Child_Holding" RightTapped="Child_RightTapped" >
    <FlyoutBase.AttachedFlyout>
        <Flyout >
            <Border Padding="4">
                ...
            </Border>
        </Flyout>
    </FlyoutBase.AttachedFlyout>
    <TextBlock .../>
</StackPanel>

As you see, you can add Flyouts for any Element, you will have to manage both events, holding and righttapped, to make appear its flyout:

var uiSender = sender as UIElement;
var flyout = (FlyoutBase)uiSender.GetValue(FlyoutBase.AttachedFlyoutProperty);
flyout.ShowAt(uiSender as FrameworkElement);

As I explain at the beginning, both parent and child Flyouts will close.

We need to create our own Flyout, that means creating a Popup with a content, manage how it appears, the datacontext and the virtual keyboard.

Custom Flyout

Due to you cannot inherit Flyout, we will create one from scratch as DependencyObject. We will call it TemplatedFlyout.

Content Template

The first property it has is the Template that the Flyout will show:

#region Template
public DataTemplate Template
{
    get { return (DataTemplate)GetValue(TemplateProperty); }
    set { SetValue(TemplateProperty, value); }
}

public static readonly DependencyProperty TemplateProperty =
    DependencyProperty.Register(nameof(Template), typeof(DataTemplate),
 typeof(TemplatedFlyout), new PropertyMetadata(null));
#endregion

Initialization

The control that has this Templated Flyout, will call initialization when this is attached:

private Popup popup;
private FrameworkElement senderElement;
private FrameworkElement frameworkContent;
public void Initialize(UIElement sender)
{
    senderElement = sender as FrameworkElement;
    senderElement.DataContextChanged += (s,e)=> frameworkContent.DataContext = 
		senderElement.DataContext;

    popup = new Popup
    {
        IsLightDismissEnabled = true,
        ChildTransitions = new TransitionCollection()
    };

    popup.ChildTransitions.Add(new PaneThemeTransition { Edge =
 EdgeTransitionLocation.Bottom });

    frameworkContent = Template.LoadContent() as FrameworkElement;
    frameworkContent.DataContext = senderElement.DataContext;

    popup.Child = frameworkContent;

    FocusKeeper();

    sender.Tapped += (s,e)=> Show();
}

To understand this initialization:

  • Sender is the element that has the Templated Flyout as attached property
  • The datacontext could be null at the beginning, so we need to manage its changes
  • In this case the transition will make appear the flyout from the bottom.
  • The content of the Popup will be an instance of the DataTemplate
  • FocusKeeper is a workaround method to avoid closing the Popup when the virtual keyboard hides

Keeping the Popup open

FocusKeeper is necessary because visually the keyboard is Visible when the Popup is Closed but the property of the InputPane IsOpen is false.
To handle if the Popup must still open:

bool keyboardOpen = false;
InputPane keyboard;
private void FocusKeeper()
{
    keyboard = InputPane.GetForCurrentView();

    popup.Closed += (s, e) =>
    {
        if (keyboardOpen)
            Popup.IsOpen = true;
    };

    if (keyboard != null)
    {
        keyboard.Showing += (s, e) => keyboardOpen = true;
        keyboard.Hiding += (s, e) => keyboardOpen = false;
    }
}

This will only allow to hide the Popup if the keyboard is not really visible.

Adjusting the vertical position of the Popup

In order to have an offset from a position from the screen, we need know which element will be taken. To do that we will add another dependency property called Container.

In the case of Universal Characters Map, you can increase the size of the ‘command bar’ so we cannot hardcode the offset.

#region Container
public FrameworkElement Container
{
    get { return (FrameworkElement)GetValue(ContainerProperty); }
    set
    {
        SetValue(ContainerProperty, value);
    }
}

public static readonly DependencyProperty ContainerProperty =
DependencyProperty.Register(nameof(Container), typeof(FrameworkElement),
typeof(TemplatedFlyout), new PropertyMetadata(null));
#endregion

Show the Popup

we just need to create the method Show when the attached control is tapped:

public void Show()
{
    popup.RequestedTheme = ((Window.Current.Content as Frame).Content as
 Page).RequestedTheme;

    var h = frameworkContent.Height + Container?.ActualHeight;

    popup.SetValue(Canvas.TopProperty, Window.Current.Bounds.Height - h);

    popup.IsOpen = true;

    if(frameworkContent is Panel)
    {
        var panel = frameworkContent as Panel;
        if(panel.Children.Any())
        {
            if(panel.Children.First() is Control)
            {
                (panel.Children.First() as Control).Focus(FocusState.Keyboard);
            }
        }
    }
}

I have added a way to keep the theme in the Popup, the offset, even Focus a Textbox when the Popup appears.

Attached Property

To add the Templated Flyout in XAML we need an attached property like the following:

public class Extensions : DependencyObject

   #region Flyout Property
   public static void SetFlyout(UIElement element, TemplatedFlyout value)
   {
       element.SetValue(FlyoutProperty, value);
   }
   public static TemplatedFlyout GetFlyout(UIElement element)
   {
       return (TemplatedFlyout)element.GetValue(FlyoutProperty);
   }

   public static readonly DependencyProperty FlyoutProperty = 
       DependencyProperty.RegisterAttached(nameof(FlyoutProperty),
           typeof(TemplatedFlyout), typeof(Extensions), 
new PropertyMetadata(null, TemplatedFlyoutChanged));

    private static void TemplatedFlyoutChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
    {
        var uiSender = d as UIElement;
        var flyout  = e.NewValue as TemplatedFlyout;

        flyout.Initialize(uiSender);
    }
    #endregion
   
}

As we see, here is where we attach the element with the initialization of the Flyout.

Example

Suppose we have a grid in the bottom part of the Window, and we add the following button:

<Button x:Name="SearchButton" Background="Transparent" BorderThickness="0" Height="42">
<SymbolIcon Symbol="Find"/>
   <a:Extensions.Flyout>
      <c:TemplatedFlyout Template="{StaticResource SearchTemplate}" Container="{Binding ElementName=CommandsGrid}"/>
    </a:Extensions.Flyout>
</Button>

Where ‘CommandsGrid’ is the container of the Button.

Conclusions

With all this analysis, now we know what’s the difference between a Popup and a Flyout, and a way to solve some behaviors of the Flyouts using a new Flyout that handles the virtual keyboard and allows child Flyouts.

As always, state of art of UWP at @juanpaexpedite

And the sourcecode of the Advanced Flyout: github