The interoperation between Visual layer and XAML layer in Creators Update

If you are using Composition APIs in November Update, it's time to know that many things are changed in Creators Update. Note that the changes start in Anniversary Update but since the Creators Update has come, you should know the newest ones.

Offset is not the same as before

Consider this situation in XAML:

<Grid Background="Black">
        <Border
            x:Name="Border"
            Width="200"
            Height="200"
            HorizontalAlignment="Center"
            VerticalAlignment="Center"
            Background="White" />
</Grid>

And look at the code below, what's the final effect you see on screen in Creators Update?

var visual = ElementCompositionPreview.GetElementVisual(Border);
visual.Offset = new Vector3(100, 100, 0);

Actually, the Border would stay at the center of the outer Grid.

If you target the SDK version back to Build 10586, the Border will has a offset to (100,100,0).

So if you want the same effect in November Update, what should you do? You should wrap the Border you want to operate with a Border(or a Canvas control) being central in the outer Grid. It's introduced in a official document(see this).

<Grid Background="Black">
        <Border HorizontalAlignment="Center" VerticalAlignment="Center">
            <Border
                x:Name="Border"
                Width="200"
                Height="200"
                Background="White" />
        </Border>
</Grid>

Apparently, it's no good to do like this because it adds the deep of XAML hierarchy and will result in bad performance.Actually there is a new way to implement this.

A long time ago I come up with an issue in this. And a long time later, the dev of Microsoft replies me with a new solution:

ElementCompositionPreview.SetIsTranslationEnabled(Border, true);

var visual = ElementCompositionPreview.GetElementVisual(Border);
visual.Properties.InsertVector3("Translation", new Vector3(100, 100, 0));

First of all, you must enable the translation property of Border. Then you use the translation property like offset before. You would like to encapsulate those as extension methods to make it simple:

private const string TRANSLATION = "Translation";

public static Visual GetVisual(this UIElement element)
{
    var visual = ElementCompositionPreview.GetElementVisual(element);
    ElementCompositionPreview.SetIsTranslationEnabled(element, true);
    var properties = visual.Properties;
    properties.InsertVector3(TRANSLATION, Vector3.Zero);
    return visual;
}

public static void SetTranslation(this Visual set, Vector3 value)
{
    set.Properties.InsertVector3(TRANSLATION, value);
}

public static Vector3 GetTranslation(this Visual visual)
{
    visual.Properties.TryGetVector3(TRANSLATION, out Vector3 value);
    return value;
}

XAML opacity & Visual opacity

Assume that there is a border whose Opacity in XAML is 0.5f and it the opacity in Visual is 0.8f, what's the final opacity being rendered on Screen?

Well, it depends.

First:

border.Opacity = 0.5f;
border.GetVisual().Opacity = 0.7f;

Those code result in a border with 70% opacity.

Second:

border.GetVisual().Opacity = 0.7f;
border.Opacity = 0.5f;

Those code result in a border with 50% opacity.

See any differences? The final effect is corresponding to the latest operation you do with its opacity property. To include, the XAML opacity will affect the Visual opacity literally, but the Visual opacity will NOT affect the XAML opacity. But setting one of those value will effect the final effect you see on screen. It's weird, but it's true.