Jump to content

Tips and tricks for using XAML controls in your universal Windows apps


Recommended Posts

Guest Windows Apps Team
Posted

This post was written by Rohan Thakkar, Program Manager 2 - Developer Ecosystem Platform on Operating Systems Group at Microsoft.

 

At //build 2014 we introduced the ability to build universal Windows apps, which are able to share a large amount of code between Windows 8.1 and Windows Phone 8.1 projects. In particular, three sessions at //build discussed the important features for developers working with XAML:

 

To follow up from those talks, we wanted to share with you the golflink sample app used for our demos and use it as a basis to share a number of tips and tricks for working with XAML controls in universal apps. For more background on XAML basics, refer to Create your first Windows Runtime app using C# or Visual Basic, Creating a UI (XAML), and Developing apps (XAML) in the documentation.

Adaptive UI

 

Sharing common pages

 

When sharing a page across Windows and Windows Phone projects, the first thing you must tackle is to ensure Windows has a software back button for in-app navigation and Windows Phone has a hardware back button for in-app navigation. The sample demonstrates a CommonPage.XAML and how to tackle the back button problem. We have done this using a separate user control, PageTitleUserControl.xaml, for Windows and Windows Phone that will be instantiated from the CommonPage in the shared project. You need to pass in a reference to the NavigationHelper for the back navigation.

public
CommonPage()

{

this
.InitializeComponent();

this
.navigationHelper =
new
NavigationHelper(
this
);

this
.InsertPageTitleUserControl();

 

this
.navigationHelper.LoadState += navigationHelper_LoadState;

this
.navigationHelper.SaveState += navigationHelper_SaveState;

}

private
void
InsertPageTitleUserControl()

 

PageTitleUserControl pageTitle =
new
PageTitleUserControl(
this
.navigationHelper);

pageTitle.PageTitle =
"Common page"
;

pageTitle.AppName =
"APP NAME"
;

rootGrid.Children.Add(pageTitle);

Grid.SetRow(pageTitle, 0);

}

 

Sharing UserControls

 

UserControls can be different, like in the above sample, but be used in a shared page. The best and most common use is to have bunch of shared UserControls (think fragmentsJ) for common parts of the UI and use them for respective XAML pages (views). In the golflink sample, we could have used them more heavily. However, to demonstrate their usefulness, check out the Shared\UserControls\ProfileControl.xaml and its usage in HubPage.XAML.

Sharing Styles

 

Sometimes you have unique styles for respective frameworks and share them. This is a nice trick that can be very handy.

In golflink sample, Windows\Styles\Styles.xaml has a resource dictionary with a set of unique styles that exist by default on Windows Phone 8.1’s generic.xaml. These styles (and maybe others) must be defined for Windows projects to be able to share the XAML with phone. Let us take a look at our example.

Windows\Styles\Styles.xaml

<
ResourceDictionary

xmlns
="

xmlns:x
="

xmlns:local
="using:golflink.Styles">

 

<
Style
TargetType
="TextBlock"
x:Key
="ListViewItemSubheaderTextBlockStyle">

<
Setter
Property
="FontSize"
Value
="15"/>

<
Setter
Property
="Margin"
Value
="0,6,0,0"/>

</
Style
>

<
Style
TargetType
="TextBlock"
x:Key
="ListViewItemContentTextBlockStyle"/>

<
Style
TargetType
="TextBlock"
x:Key
="ListViewItemTextBlockStyle"/>

<
SolidColorBrush
Color
="Blue"
x:Key
="PhoneAccentBrush"/>

<
SolidColorBrush
Color
="White"
x:Key
="PhoneForegroundBrush"/>

<
x:Double
x:Key
="ContentControlFontSize">
20.26
</
x:Double
>

</
ResourceDictionary
>

 

ListViewItemSubHeaderTextBoxStyle does not currently exist on Windows 8.1 but it does on Phone 8.1. We define it here.

Similarly on the phone side we might require a style with a key shared with Windows to behave differently. We put it under Phone\Styles\Styles.xaml.

Now, as you might imagine, these were styles unique to each project. The styles that are common to both projects are in shared project’s app.xaml (Shared\App.xaml).

Here, you will also merge the Styles.xaml’s resource dictionary using the highlighted mark up:

<
Application

x:Class
="golflink.App"

xmlns
="

xmlns:x
="

xmlns:local
="using:golflink"

xmlns:localData
="using:Shared">

 

<
Application.Resources
>

<!-- Application-specific resources -->

<
ResourceDictionary
>

<
ResourceDictionary.MergedDictionaries
>

<
ResourceDictionary
Source
="/Styles/Styles.xaml"/>

</
ResourceDictionary.MergedDictionaries
>

<
x:Double
x:Key
="largeCellHeightPercent">
0.392
</
x:Double
>

<
x:Double
x:Key
="largeCellWidthPercent">
0.392
</
x:Double
>

 

 

<
x:Double
x:Key
="mediumCellHeightPercent">
0.205
</
x:Double
>

<
x:Double
x:Key
="mediumCellWidthPercent">
0.205
</
x:Double
>

 

<
x:Double
x:Key
="smallCellHeightPercent">
0.138
</
x:Double
>

<
x:Double
x:Key
="smallCellWidthPercent">
0.138
</
x:Double
>

</
ResourceDictionary
>

</
Application.Resources
>

</
Application
>

 

The end result is a nice way to merge dictionaries and share styles where appropriate.

Window-based width adaption

 

Sometimes you want to set the width of certain controls to be relative to the window size (or dimensions of the device). For example, on phone, a HubSections width should ideally be 90% of window width. The percentage-based dimensions can be handy at many places, and here we describe simple steps on how to achieve the goal using behaviors. An important note here is that one might get carried away and use percentage-based width/height everywhere, but you should step back and realize the need for it. Existing layout primitives like Grid/StackPanel coupled with alignment properties provide a pretty powerful adaptive UI mechanism. So, the take away is use WindowDimensionBehavior for percentage-based widths only when you absolutely cannot use Grid/StackPanel. Here is how you would do it:

Step 1. Add Behaviors SDK. Right-click both projects Windows/Windows Phone individually and add reference. Select Extensions SDK -> Behaviors SDK.

f4dca46004e16e35eed5a55610fbb161.png

cb82d41633dd6b79c008c95ba88569dc.png

Step 2. Create a shared Helper class, WindowDimensionBehavior.cs:

using
Microsoft.XAML.Interactivity;

using
Windows.UI.XAML;

using
Windows.UI.XAML.Controls;

 

namespace
golflink.Helpers

{

 

[Microsoft.XAML.Interactivity.TypeConstraint(
typeof
(FrameworkElement))]

class
WindowDimensionBehavior : DependencyObject, IBehavior

{

public
WindowDimensionBehavior()

{

this
.WidthMultiple = 1;

this
.HeightMultiple = 1;

this
.HeightPercentage =
double
.NaN;

this
.WidthPercentage =
double
.NaN;

}

public
DependencyObject AssociatedObject { get; set; }

 

public
FrameworkElement TypedObject { get; set; }

public
int
WidthMultiple { get; set; }

 

public
double
WidthPercentage { get; set; }

 

public
int
HeightMultiple { get; set; }

 

public
double
HeightPercentage { get; set; }

 

public
void
Attach(DependencyObject associatedObject)

{

this
.AssociatedObject =
this
.TypedObject = associatedObject
as
FrameworkElement;

 

this
.TypedObject.Loaded += TypedObject_Loaded;

Window.Current.SizeChanged +=Current_SizeChanged;

 

}

 

void
TypedObject_Loaded(
object
sender, RoutedEventArgs e)

{

Handle();

}

 

void
Current_SizeChanged(
object
sender, Windows.UI.Core.WindowSizeChangedEventArgs e)

{

Handle();

}

 

private
void
Handle()

{

var frameWorkElement = (
this
.TypedObject
as
FrameworkElement);

 

//I base all the percentage calculations on shortest dimension, you can modify this depending on your layouts requirements.

double
shortestDimension = (Window.Current.Bounds.Width <= Window.Current.Bounds.Height) ?

Window.Current.Bounds.Width : Window.Current.Bounds.Height;

 

if
(frameWorkElement !=
null
)

{

if
(
this
.WidthPercentage!=
double
.NaN)

frameWorkElement.Width = shortestDimension *
this
.WidthPercentage *
this
.WidthMultiple;

if
(
this
.HeightPercentage!=
double
.NaN)

frameWorkElement.Height = shortestDimension *
this
.HeightPercentage *
this
.HeightMultiple;

}

}

 

public
void
Detach()

{

Window.Current.SizeChanged -= Current_SizeChanged;

(
this
.AssociatedObject
as
Control).Loaded -= TypedObject_Loaded;

 

}

}

}

 

Step 3. Use it in XAML

Don’t forget to add xmlns reference:

xmlns:Interactivity="using:Microsoft.XAML.Interactivity"

 

Then in the actual Hub section where you want to make the width twice of 90% of the window width:

<
HubSection
x:Uid
="Section2Header"
Header
="MY GAME"
DataContext
="{Binding Profile}">

<
Interactivity:Interaction.Behaviors
>

<
helpers:WindowDimensionBehavior
WidthMultiple
="2"
WidthPercentage
="0.9"/>

</
Interactivity:Interaction.Behaviors
>

<
DataTemplate
>

 

And use it responsibly.

Revisiting the goodness of layout primitives (Grid/StackPanel)

 

The Windows\Players.xaml page makes almost no use of the WindowDimensionBehavior mentioned above. 99% of the layout is done using basic layout primitives like Grid, StackPanel, ListView and GridView. Make good use of the HorizontalAlignment/VerticalAlignment and HorizontalContentAlignment/VerticalContentAlignment properties coupled with the magic of Grid’s “star” capabilities.

On the other hand, on the Phone’s Players.xaml page, we have extensively used behaviors (not recommended, but left there for comparison).

Viewbox

 

This can be handy at times when you want the text font to scale with window dimension. We used it in a couple of places in the project (an exercise for you to search and learn why; let us know if you think of other ways to achieve the same desired scenario). Just knowing that this control exists for your layout magic is super useful.

VisualStateManager

 

Use it along with the Window_SizeChanged event to swap out item templates or show/hide different controls on your layout. Unfortunately, we haven’t used it in our demo app. However, there is nothing new or fancy here to demonstrate. XAML experts know the power of VSM. Folks who are not familiar with VSM can take a look at Quickstart: Designing apps for different window sizes.

Test test test…

 

Universal apps will have a massively diverse dimensional reach. It is very important to test your app’s layouts in different resolutions and dimensions. Remember, width is not the only thing that varies. Height also varies significantly. An easy way to test is using Simulator for Windows and Emulator for phone or the designer.

afb90705dc33e5b66ba5888036451a13.png

The Golflink app has bugs; we could not fix all of them. Curious readers can try and see which layouts have problems.

Specific common controls but different behaviors

 

Hub

 

Windows Store Apps using XAML Hub share the same API as Windows Hub, but it looks and feels like the Phone 8.0 Panorama. When authoring an app using Phone Hub here are a few things to note or do differently.

  • HubSection’s width is by default set to 90% of window width. If the content of the section is wider than this, it will get clipped.
  • If you want the HubSection to expand to match the width of the content, you need to set the width of HubSection to Auto
     

    <HubSection Width="Auto"/>


  • The recommended way to have a wide HubSection is to make the section’s width equal to a multiple of 90% of the window width. There are different ways to achieve this. In the sample we have used behaviors (recommendation from Jerry Nixon, thanks!) and shared a behavior class to achieve this. Check the adaptive UI section for step-by-step instructions on how to use WindowDimensionBehavior.cs.
  • Use the Hub.SectionsInViewChanged event to identify SectionsInView. This is a replacement for the 8.0 Panorama.SelectionChanged event and SelectedIndex. In the golflink sample we have used it to show/hide app bar for “recent” section.
  • Hub is designed to be used with Orientation=”horizontal” ONLY. Do not use it in Orientation=”vertical”.

private
void
Hub_SectionsInViewChanged(
object
sender, SectionsInViewChangedEventArgs e)

{

if
(Hub.SectionsInView!=
null
&& Hub.SectionsInView.Count>0)

if
(Hub.SectionsInView[0].Name==
"recent"
)

{

appBar.ClosedDisplayMode = AppBarClosedDisplayMode.Compact;

(appBar.PrimaryCommands[0]
as
AppBarButton).Visibility = Windows.UI.XAML.Visibility.Visible;

}

else

{

appBar.ClosedDisplayMode = AppBarClosedDisplayMode.Minimal;

(appBar.PrimaryCommands[0]
as
AppBarButton).Visibility = Windows.UI.XAML.Visibility.Collapsed;

}

}

 

Tip: Two section Hubs don’t wrap. This is by design. Having a Hub with fewer than three sections is not recommended UX and supporting wrapping for two section Hubs was very expensive.

SemanticZoom

 

SemanticZoom is available on both platforms but the interaction model varies significantly.

Windows behavior

 

It is the same as you know on Windows 8.1. You pinch on the ListView/GridView within a SemanticZoom to get the zoomed out view. Our sample uses SemanticZoom in Players.XAML

889257e7f4b248a9d1e1be2b1af7ecc4.png

After you pinch the contacts you get the ZoomedOut view:

64d8c01a4999fa5c54916cd0990c03a3.png

Windows Phone behavior

 

In the phone world, this used to be referred to as a JumpList in LongListSelector, and you invoke it by tapping on the group headers. Interaction for it stays the same. When the user taps the group header, SemanticZoom.ZoomedOutView is invoked with an animation similar to native phone jumplists. Here is an image to remind you what we are talking about. A sample for this is available in golflink.Phone project’s Players.xaml “all” players pivot item. Justification for the divergent interaction model has been that tablets are two-handed devices where the device is held with one hand and the screen is pinched with the other whereas phones are one-handed devices, and to invoke the zoomed out view (jump list) you only need to tap on the group header.

ba15b31fd8fc5ba9a47c70996e532cc1.png084d6c9fd9f91ff32544c6fc2552a5fa.png

Tip: For the Listview on Windows Phone 8.1 XAML, do not forget to add a width to the ListView item template to avoid a horizontal bouncing bug. Check the sample comments in Players.XAML

DatePicker/TimePicker

 

DatePicker and TimePicker APIs are both available on the Windows 8.1 and Windows Phone 8.1 XAML stack, but they look and interact differently. Settings.XAML includes a basic sample. Here are a few screenshots.

Windows behavior

 

dab0e12d3bd2ec38da5e67a9d74d33f3.png520248a2f50cba9c103d5382ea3ca0ad.png

 

Windows Phone behavior

1d439ccdfe482616fb22f9ba6e69c741.png788870782de53b6046e406fd5425a5b7.png

ComboBox

Windows behavior

 

8f28d7bb5d4227dde227b6999a7469eb.png

 

Windows Phone behavior

The Phone ComboBox item list expands in place when there are up to five items, but will turn into a picker flyout for more than five items.

823df79c253c9c9efcddd43291330d0a.pngff0188be0d53f173d6ae90cd181f0ccb.png

MenuFlyout

Similar to DatePicker/TimePicker. The experience for MenuFlyout is unique to each OS. The sample is in Settings.XAML page.

Windows behavior

 

On Windows it’s a simple flyout with menu items.

ed45b49d91649e85e7bd555fe019863f.png

Windows Phone behavior

Windows Phone has an “elevator/escalator” animation (similar to ContextMenu from WPToolkit).

94c16516d856536b3eb92f4eff7a6012.png

Phone-only control APIs

 

There are a few controls that we added after Windows 8.1 shipped that are only a part of the Windows Phone 8.1 stack (for now, yes, we understand and feel the pain of divergence).

Listview/Gridview additional properties

 

Converters for zoomed out view (jumplist)

 

JumpListItemBackgroundConverter/JumpListItemForegroundConverter helps with setting the right colors for the Jumplist (zoomed out semantic zoom view). Used in Player.xaml’s “all” pivot item.

ReorderMode

 

It is very easy to invoke reorder mode now. All you need is a two-way binding with the collection on your ListView and then Enable/Disable this property on the ListView. You will see the usage on Windows Phone’s Players.xaml page (“favorites” pivot item).

e1f73cd8dc3fbc7fa4594def2fde3d1d.png

However, there is no ReorderMode_changed event, so you need to use data binding to get the state changes of ReorderMode. Here is how we have done it in the app:

Players.xaml

<
Page

x:Class
="golflink.Pages.Players"

xmlns
="

xmlns:x
="

xmlns:local
="using:golflink.Pages"

xmlns:d
="

xmlns:mc
="

xmlns:prim
="using:Windows.UI.XAML.Controls.Primitives"

xmlns:Interactivity
="using:Microsoft.XAML.Interactivity"

xmlns:helpers
="using:golflink.Helpers"

mc:Ignorable
="d"
Name
="rootPage">

<
ListView
Name
="favoritesListView"
ItemsSource
="{Binding RecentPlayers}"

ReorderMode
="{Binding ReorderMode, ElementName=rootPage, Mode=TwoWay}"

ItemTemplate
="{StaticResource RecentListViewItemTemplate}">

</
ListView
>

 

Players.xaml.cs code behind

public
sealed
partial
class
Players : Page, INotifyPropertyChanged

{

//other usual methods

 

private
void
editAppBarButton_Click(
object
sender, RoutedEventArgs e)

{

this
.ReorderMode = ListViewReorderMode.Enabled;

ReorderModeChanged();

}

 

private
void
acceptAppBarButton_Click(
object
sender, RoutedEventArgs e)

{

this
.ReorderMode = ListViewReorderMode.Disabled;

ReorderModeChanged();

}

 

private
void
ReorderModeChanged()

{

if
(
this
.ReorderMode == ListViewReorderMode.Enabled)

{

playerPivot.IsLocked =
true
;
//lock the pivot

editAppBarButton.Visibility = Windows.UI.XAML.Visibility.Collapsed;

acceptAppBarButton.Visibility = Windows.UI.XAML.Visibility.Visible;

}

else

{

playerPivot.IsLocked =
false
;

editAppBarButton.Visibility = Windows.UI.XAML.Visibility.Visible;

acceptAppBarButton.Visibility = Windows.UI.XAML.Visibility.Collapsed;

}

}

 

private
ListViewReorderMode _reorderMode = ListViewReorderMode.Disabled;

public
ListViewReorderMode ReorderMode

{

get

{

return
_reorderMode;

}

set

{

if
(_reorderMode !=
value
)

{

_reorderMode =
value
;

NotifyPropertyChanged();

this
.ReorderModeChanged();

}

}

}

 

public
event
PropertyChangedEventHandler PropertyChanged;

private
void
NotifyPropertyChanged([CallerMemberName]
string
propertyName =
""
)

{

PropertyChangedEventHandler handler = PropertyChanged;

if
(
null
!= handler)

{

handler(
this
,
new
PropertyChangedEventArgs(propertyName));

}

}

}

 

Pivot

 

Pivot for Windows Phone 8.1 XAML shares the same behavior as Windows Phone 8.0, but the API is not available in Windows 8.1 XAML. This makes it tricky to share the page across the two projects in universal apps.

In our example, we have two separate XAML files. The Phone side uses the Pivot and the Windows side uses a custom design implementation that suits the app’s content.

The Pivot API in Windows Phone 8.1 XAML SDK is same as the Silverlight 8.0 Pivot API. One delightful feature that was included was Pivot.SlideInAnimationGroup="GroupOne". The intent of this property is to slide in FrameworkElements when the selected PivotItem changes. All the elements in a group slide in together and you can have three different levels (groups). Use it responsibly. Check out Phone’s Players.xaml for the usage example.

StatusBar, margins on pages and headers

 

StatusBar (System tray) is now always visible on Windows Phone 8.1 unless explicitly hidden. Its opacity is set to 0. To explain this part, let us define CoreWindowBounds as the screen window, the size of the phone window in logical pixels. VisibleBounds is the size of the visible region of the window (CoreWindowBounds minus size of StatusBar+AppBar).

By default, the page’s content takes the VisibleBounds, however the page background, when set, takes the CoreWindowBounds. If you set a background on the page, it goes all the way from top to bottom, behind the app bar and status bar. But the content of the page stays in the visible region.

To be clear, let’s look at the basic XAML below:

<
Page

x:Class
="App29.MainPage"

xmlns
="

xmlns:x
="

xmlns:local
="using:App29"

xmlns:d
="

xmlns:mc
="

mc:Ignorable
="d"

Background
="Red">

 

<
Grid
Background
="Yellow">

 

</
Grid
>

<
Page.BottomAppBar
>

<
CommandBar
Name
="appBar"
Visibility
="Visible"
Opacity
="0.5">

<
CommandBar.PrimaryCommands
>

<
AppBarButton
Icon
="Edit"

Label
="edit"
Name
="editAppBarButton"/>

</
CommandBar.PrimaryCommands
>

</
CommandBar
>

</
Page.BottomAppBar
>

</
Page
>

 

This is the result of the page:

a9a5f926bc7af023e297a25fd08f0c00.png

This is good. Now you don’t need to worry about the content of the page being occluded by either StatusBar or AppBar.

Additionally, Pivot/Hub templates already offset their respective headers to account for a visible/hidden StatusBar, so you don’t need to worry about it.

Tip: You should be careful when toggling the state of the appbar’s ClosedDisplayMode as it resizes the content and could result in the page jumping. We recommend toggling the state of the appbar only when you have a ScrollViewer on that particular page (or HubSection or PivotItem).

Then, unfortunately, one of the scenarios was not caught earlier. It is better that we list the workaround here than to have you go through an ordeal trying to fix the issue.

If you have a Jumplist (SemanticZoom) as a child of a PivotItem/HubSection, the transition is not smooth from the ZoomedOut to ZoomedIn view because of this margin adjustment and because the Jumplist hides the StatusBar automatically. The workaround here is to disable the page resizing. It is important to note that this is a global, app-wide setting. So don’t forget to re-enable VisibleWindow when you leave the page.

protected
override
void
OnNavigatedTo(NavigationEventArgs e)

{

navigationHelper.OnNavigatedTo(e);

(Windows.UI.ViewManagement.ApplicationView.GetForCurrentView()).

SetDesiredBoundsMode(Windows.UI.ViewManagement.ApplicationViewBoundsMode.UseCoreWindow);

}

 

protected
override
void
OnNavigatedFrom(NavigationEventArgs e)

{

(Windows.UI.ViewManagement.ApplicationView.GetForCurrentView()).

SetDesiredBoundsMode(Windows.UI.ViewManagement.ApplicationViewBoundsMode.UseVisible);

navigationHelper.OnNavigatedFrom(e);

}

 

The PivotHeaders are fine and in place. All you need to do is ensure your content is not occluded by the AppBar (CommandBar). Add compensation padding at the end of the content to account for the app bar. In our case, we do it using the footer property on ListView:

<
ListView.FooterTemplate
>

<
DataTemplate
>

<
Rectangle
Fill
="Transparent"
Height
="60"/>

</
DataTemplate
>

</
ListView.FooterTemplate
>

 

ContentDialog

 

This is a custom message dialog with phone dialog UX that is completely customizable. You can also cancel the closing of the dialog if the result of the dialog is not to your app’s liking (example terms and conditions are not accepted).

A basic sample can be found on settings.xaml page for phone project.

93e3f020d161d7431be486116b2ad766.png

AutoSuggestBox

The Windows 8.1 functionality equivalent for this would be SearchBox, which allows you to do suggestions. AutoSuggestBox is lightweight, without Search integration, and suggestions in a list with ItemsControl. A sample can be found on Settings.xaml page for phone.

44d6b7e1c9e5bb2d27bd4e77e9ca3c11.png

ListPickerFlyout

Unique to Windows Phone, you can now have ListPickerFlyouts to display a list of content in a pop-up-like fullscreen window. Sample usage in Settings.xaml of phone project

a99ff20979c8e947216027f84223ad64.png

Animations

The talk on animation at //build pretty much covered everything. The sample demonstrates the usage from the talk. Here is a brief summary:

  • All the animations existing on Windows also exist on Phone. Some might be modified for phone UX (for example, PointerDownThemeAnimation is more like the tilt effect on phone; refer to the Profile.xaml usercontrol sample).
  • Phone has added a new concept of NavigationThemeTransitions on pages. There are three different types of navigation animations: CommonNavigationTransitionInfo (default turnstile animation), SlideInNavigationTransitionInfo and ContinuumNavigationTransitionInfo. These are all covered in the animations talk and used in the sample. This could be a differentiating factor between a four star and a five star app. For more details refer to Kunal’s talk from Build - Animations in Windows Phone XAML Apps
  • Here is an example of how to define it:


    <
    Page.Transitions
    >

    <
    TransitionCollection
    >

    <
    NavigationThemeTransition
    >

    <
    NavigationThemeTransition.DefaultNavigationTransitionInfo
    >

    <
    CommonNavigationTransitionInfoSlideNavigationTransitionInfo
    />

    </
    NavigationThemeTransition.DefaultNavigationTransitionInfo
    >

    </
    NavigationThemeTransition
    >

    </
    TransitionCollection
    >

    </
    Page.Transitions
    >


 

When going from page A to page B, the framework plays the animation as defined on page B. And then, when navigating back from page B to page A, the framework will play the right animation contextual to the navigation (example - in this case slide-out page B).

fbf11745c9f1754c3e75bb3e29930a25.png

XAMLToolkit

Almost everything that was in WPToolkit is now part of the Universal XAML framework. What are you looking for in XAMLToolkit? We really want to know. Your feedback helps us prioritize the work we do.

Conclusion

 

Phew. . . that was a lot of content. We have worked really hard to provide this level of convergence in universal apps. We know it is not 100% perfect but it’s a step in the right direction. We hope this post helped you get past a few glitches you might have encountered when writing your universal app.

Thank you for reading this far and feel free to reach out with questions in comments or directly 929bf1aa83adc29d31288f86c17d606a._.gif

 

Continue reading...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...