Intro

I like how Facebook shows pictures in my feed. Facebook image gallery can look similar as depicted above. This style is common for the web and for the native Facebook apps.

The gallery is great from UX perspective. Part of photos is available immediately, so no need to do additional few clicks if they are not catchy. There is a counter, which identifies how many pictures are left in the full-screen mode. And images are arranged differently depending on aspect ratio and quantity, so it brings a cool dynamic style. With all that said why not to have the same look gallery in any other UWP app :).

Possible solutions

A naive implementation can be approached with the idea to place ItemsControl in the top and bottom rows of Grid, bind them to two collections and somehow manage a number of visible items for both rows. But it increases code complexity and causes XAML duplications. Two data bindings might lead to the situations when the rows are rendered not in the same time. Eventually, dynamic behavior is lost and the implementation is prone to have performance issues.

I achieved the desired result by implementing a custom panel, where I override MeasureOverride and ArrangeOverride methods. These two virtual methods contain core logic of any class inherited from FrameworkElement. They involved in every layout cycle. MeasureOverride is responsible for calculating the final size, which will be taken by a framework element when it’s been rendered. The purpose of ArrangeOverride is to position a framework element and its children with the given size. These methods well described in Windows Dev Center documentation.

When the custom panel was done, I used it as ItemsPanelTemplate for ItemsControl. ItemsControl is a lightweight list-based control. No reason in my case to have a selection or apply virtualization, so using ListView or GridView is unnecessary.

Step by step implementation

First I define a class and inherit it from Windows.UI.Xaml.Controls.Panel. I named my custom panel ImageGalleryPanel. I also want to manage the number of items shown in the first and second row in runtime, that’s why I expose two dependency properties ItemsInFirstRow and IntemsInSecondRow in the panel class:

Size parameter of FrameworkElement.MeassureOverride is always passed from a parent. And it’s responsibility of framework element to split up the given size among children and measure a child with the available height and width. In ImageGalleryPanel.MeasureOverride, I calculate the width for children items based on ItemsInFirstRow and ItemsInSecondRow values. Then I measure every child with calculated size. After children are measured, I return back the final size which will be taken by the panel:

When the desired size is known for every child, the system calls FrameworkElement.ArrangeOverride to position every child. In ImageGallery.ArrangeOverride, I arrange children with the desired size of a particular child and number of elements configured per a row:

The final step is to show how many photos will be available in the full mode. One of the possible ways to implement this indicator is to extend ItemsControl.ItemTemplate with a transparent Border and TextBlock. TextBlock contains a number equals to hidden items. Border overlay and TextBlock are only visible for the last item:

For sake of simplicity, I define a ViewModel for an item as an anonymous type and declare OverlayVisiblity as a type of Windows.UI.Xaml.Visiblity. In a real project, I would keep above logic in a separated class and convert bool to Visiblity with IValueConverter.

Placeholders

If you launch the app, you will immediately notice how elements have been arranged. It’s because the panel is measured and arranged in few cycles. At the first cycle the final size of images is unknown because they are not loaded yet, so we only see the overlay and the number of items in full mode. As soon as images are loaded, the panel measures and arranges children again. It doesn’t look good at all. And will look worse, if images will be downloaded from the web.

I want to show a placeholder for every child item immediately the page loaded and hide the placeholders when images become visible:

To show placeholders, I extended the DataTemplate with ViewBox. This piece of XAML does the trick:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

<DataTemplatex:Key="ItemTemplate">

<Grid>

<Viewboxx:Name="Placeholder">

<Border Height="3"

Width="4"

Opacity=".1"

Background="#000000"/>

</Viewbox>

<Image Source="{Binding ImageUri}"/>

<Borderx:Name="Overlay"

Opacity=".2"

Visibility="{Binding OverlayVisiblity}"

Background="#000000"/>

<TextBlockx:Name="Counter"

FontSize="30"

FontWeight="SemiBold"

Foreground="#FFFFFF"

VerticalAlignment="Center"

HorizontalAlignment="Center"

Visibility="{Binding OverlayVisiblity}"

Text="{Binding Counter}"/>

</Grid>

</DataTemplate>

Viewbox scales the given content to the all available space. Basically, ViewBox content is stretched to the size passed to it from the parent at the first layout cycle. I also set Height and Width of the placeholder Border proportional to the given images size. It makes the border stretched with the aspect ratio of images. When images loaded, they are shown above placeholders.

Needless to say, #MSBuild is the most wanted conference for Microsoft developers. Build 2017 took place in Seattle. I was lucky to take part in the event as an attendee. The event was interesting not only because of announcements. It’s a chance to discuss technical topics with other engineers and get answers on questions directly from Microsoft specialists.

During these days Microsoft announced their focus and shared roadmaps of different projects. From the very beginning, Satya Nadella outlined a new strategy of the company. From mobile-first and cloud-first, Microsoft is moving towards an intelligent edge, inside of which is an intelligent cloud. The company focus is shifting from devices towards where and how people interact with all gadgets they own. Microsoft erases boundaries between platforms and wants to connect people activities together with help of AI andserverless technologies.

Microsoft Intelligent Cloud

Microsoft builds intelligent cloud around its Azure services. New cloud services and serverless computing were presented at the first-day keynote:

Azure Functions Runtime is serverless application development tool. You install the runtime at your environment, deploy and launch your serverless functions there. As soon as it’s decided, you can seamlessly move the functions into the cloud. It means you don’t need to manage Microsoft Azure account if would like to try serverless computing. The minimum requirements is a machine with Windows Server 2016 or Windows 10 Creators Update with access to a SQL Server instance.

It’s worth to mention about improvements related to Azure Services management. Scott Hanselman demonstrated new possibilities of Azure Cloud Shell. Azure CLI gives you full control and flexibility. You can create 1000 instances of virtual machines on a fly with only one command. There are apps for iOS and Android to help you to manage and monitor your web-services from anywhere. Azure Cloud Shell is available in the apps also.

Microsoft Intelligent Edge

Since the last two years, Microsoft made a significant progress in artificial intelligence. The company is strong in computer vision, speech and search. They made available these technologies for other developers with Microsoft Artificial Intelligence APIs.

Microsoft intelligent edge or in other wordsAI platform is presented by cognitive services, bot framework, deep learning and data analytics tools.Cognitive services APIs documentation and code examples are available for the most popular programming languages. The company pays a big attention to customization. With help of new Custom Search, Custom Decision, and Custom Vision services, it’s easy and fast to train your model with any data, and with few clicks, you can utilize the mode through an endpoint.

Adaptive cards is an open source framework. It allows to build a UI widget with a JSON and show it in a communication channel.

If you are curious about Microsoft progress in other AI services, you can try out and experiment with them at Cognitive Services labs portal at very early stage.

There are many good examples how Microsoft helps business move forward with AI. I want to highlight a success story of UBER. It uses Microsoft Face API to identify drivers. Video broadcasting at the conference was powered by Microsoft speech recognition services.

Windows 10 Fall Creators Update

The second day was full of news about Windows, cross-device and cross-platform development. The next significant Windows 10 update is coming in Fall 2017, it’s named Microsoft Fall Creators Update. The new version of Windows includes fluent design, timeline feature, files on-demand, cloud clipboard and new Story Remix application.

Timeline feature gives users cross-device experience. A user can work with an app at his Windows PC, afterward he switches to iPhone and with help of Cortana, continues his interactions within the mobile app from the spot he left it at Windows. It works in both directions. Moreover, If the app is not on his iPhone, Cortana asks to install it from Apple Store. This amazing functionality is powered by Microsoft Graph and Project Rome. At Build, Microsoft announced Project Rome SDK for iOS.

OneDrive files on-demand gives you the possibility to access all your cloud files and folders from File Explorer without downloading them.

Copy from Windows and paste to an iPhone becomes available through Microsoft Swiftkey clipboard.

The new Creators Update also brings iTunes and Ubuntu at Windows 10. Users will be able to install this software directly from the Microsoft Store. Apart of that, Spotify for Windows 10 was promised.

New standards in cross-platform development

Microsoft does big efforts to make Windows home for all developers. They want developers for any platform to have a comprehensive set of tools to build apps. With that said, many announcements were related to cross-platform development.

First of all, they introduced XAML Standard 1.0 and .Net Standard 2.0.

XAML Standard aligns markup syntax, used at Xamarin.Forms and Windows 10. The main idea is to make it possible to re-use Windows 10 pages in Xamarin applications. Once, a TextBlock is defined in Windows 10 page markup, it will behave in the same way at Xamarin.Forms. Feel free to extend the standard specification with your proposal.

Development experience with.Net Core can be painful when you are not able to reference a NuGet package in your project. The current situation is that many NuGet packages are still not available for .Net Core applications, so the development is slow down. Worse, when this fact makes .Net Core as a not desirable technology. Microsoft is aware of this problem and wants to make it’s simpler to build a library, which works on any version of the existing frameworks: .Net Framework. Xamarin & Mono, .Net Core and UWP. The new version of .Net Standard 2.0 extends cross-platform APIs and covers the top 70% of NuGet packages.

Continuous delivery for mobile apps

Solid design and high quality are important factors for successful apps. The diversity of devices increases testing complexity and delays product releases. Health monitoring and analytics keeps an app quality in shape and gives a feedback about the app features usage. Visual Studio Mobile Center is a comprehensive solution for mobile apps testing and monitoring. It contains well known HockeyApp and Xamarin Test Cloud. Eventually, automated build and a full range of Windows devices come to the Mobile Center this fall.

Cross-platform development with Xamarin

The last announcements I want to highlight in the article are my favorites. It’s about cross-platform development with Xamarin.

Xamarin Live Player is an amazing tool. It extremely simplifies development apps using Xamarin and C#. You can change a piece of code when debugging and the changes are immediately applied. Works in the same way as live-reload in Chrome. With the Live Player, you don’t need a Mac anymore to run and test your app on iPhone. It works like a charm, just plug in an iPhone to Windows PC, choose the Live Player option in Visual Studio and that’s it. The tool is available as a preview for Windows and Mac.

Xamarin team presented a new project, the codename is Embeddinator 4000. It is a future of cross-platform development. In two words, you pack .Net code with Embeddinator into a library and utilize the library in a native iOS, Android, Mac or Linux app.

Fun

Apart from technical talks, there was a fun part. I traveled with my team mate. It was amazing to test the app we are currently working on at Microsoft devices with a different scale. We checked how the app works on Microsoft Surface Hub and Microsoft Surface Studio. I also tried Stryker software, tailored for a HoloLens device to help people to design operating rooms.

In general, I enjoyed the conference format, content and the way it was organized. Definitely, I will attend it the next year :).

Intro

Drop down selector can be used in scenarios when a user has to choose an option from a short list of values, but it doesn’t make any sense to show the whole list of values at a page. Can be useful to choose a sorting order or a filter:

There is no a similar control in UWP SDK. How to build a custom one? My intent in this article is to demonstrate how to do it with few lines of code, using based UI elements.

Base properties

Let’s name the new control DropDownButton and inherit it from Windows.UI.Xaml.Controls.Control. As usual, in the default constructor, it’s required to define DefaultStyleKey, in order to apply a style defined in Generics.xaml file:

1

2

3

4

5

6

publicDropDownButton()

{

DefaultStyleKey=typeof(DropDownButton);

}

DropDownButton needs at least ItemsSource, ItemTemplate and SelectedItem. These properties allow to bind data, apply custom view for a data item and use a selected value. And of course, they supposed to be dependency properties:

There are two visual states defined in the template, PointerDown and PointerUp. They used to show when a user taps the control. I manage the animation with overridden OnPointerPressed and OnPointerReleased methods:

Codebehind

The core logic of the control is to show the list with available options, select an option, show the selected value an close the list on user tap outside of the control boundaries.

The easiest part is to open the list with items. To achieve that, I subscribe on Tapped event and call FlyoutBase.ShowAttachedFlyout in the event handler:

1

2

3

4

5

6

7

8

9

10

11

12

13

publicDropDownButton()

{

DefaultStyleKey=typeof(DropDownButton);

Tapped+=DropDownButtonTapped;

}

privatevoidDropDownButtonTapped(objectsender,TappedRoutedEventArgse)

{

if(_rootGrid!=null)

FlyoutBase.ShowAttachedFlyout(_rootGrid);

}

Another substantial part of any custom control is OnApplyTemplate method. This method is the entry point to subscribe for events of the elements, defined in the control template. It’s very important to have this method written correctly:

WebView is a powerful UI component. It was extended in UWP with new features, which give developers more control on content rendering. I would like to highlight some of them, which I found useful.

Execution mode.

When your app is launched at desktop, WebView loads and renders html content in the UI thread. When it’s a mobile device, then html content is processed in a separated thread. If you want to override this behavior and host WebView in a non UI thread at desktop, then you need to set WebView.DefaultExecutionMode to SeparateThread value. WebView.DefaultExecutionMode is a static getter. And the only one way to set a value for that is to pass it into a constructor. So, no way to declare DefaultExecutionMode in XAML. You need to create WebView in code behind and add it to the root panel:

Only GET and POST requests can be send with WebView.NavigateWithHttpRequestMessage.

Catch and modify a request.

Every time WebView starts to load html document, it raises NavigationStarting event. At this point, it’s possible to cancel the navigation by setting Cancel property of the event arguments to true. You can use this event to catch an http GET request, add your custom headers or parameters and send it again:

In the handler you can’t access a request body, so it can be applied only for a GET. There is no way to modify POST or DELETE requests.

Handle a deep link.

UI in your app can mix html content with native pages. And navigation between html pages and native content can be done with help of mobile deep linking. In order to provide smooth experience for users, you have to handle deep links gracefully. WebView fires UnsupportedUriSchemeIdentified event, when it can’t process an URI scheme. Just subscribe for the event and process a navigation URI manually.

Windows Photos application allows a user to rotate an image and save a copy to a local storage. How would you implement the same functionality in your app?

There are two approaches:

We can get a raw pixel data of a picture and then rotate the array of bytes;

Universal Windows Platform has API, which helps to solve this task.

Let’s take a look at both of them.

Access a raw pixel data.

To access a pixel data we have to utilize a chain of objects. First of all, we need to decode an input image data with an instance of BitmapDecoder. From BitmapDecoder, we can get an instance of PixelDataProvider. And then, use PixelDataProvider.DetachPixelData to get an array of pixel data.

Rotate a pixel data clockwise.

A picture rotation implies rotation of a two-dimensional matrix. Such kind of a transformation means that columns of an input array are converted to rows of an output array and rows of the input becomes columns of the output. Taking that in account, we can express the logic of a matrix transformation in the following code:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

introw=2;

intcol=6;

//initialize input array

int[][]input=newint[row][];

for(inti=0;i<input.Length;i++)

{

input[i]=newint[col];

for(intj=0;j<input[i].Length;j++)

input[i][j]=5*i+j;

}

//rotate and put the result to output array

int[][]output=newint[col][];

for(inti=0;i<output.Length;i++)

{

output[i]=newint[row];

for(intj=0;j<output[i].Length;j++)

output[i][j]=input[input.Length-j-1][i];

}

I set variable output to a two-dimensional array of int and used number of columns as number of rows for the output. I’m using a row index of the output array to access columns of the input array. And index of an input row can be calculated from an output column index.

When dealing with a picture, we have a one-dimensional array of a pixel data and a pixel length typically is 4 bytes. The algorithm to rotate a one-dimensional array has 3 steps:

Calculate row and column indexes of a two-dimensional matrix from an index of an input array;

Calculate rotated row and column indexes;

Use the values calculated at the step 2 and convert them to one-dimensional index.

The method takes pixel data and size of a picture. When rotated row and column indexes are calculated, I’m traversing a nested loop to copy values from an input pixel to a rotated pixel. By rotated pixel, I mean a pixel from the rotated matrix.

The height of the original image should be used as a value for width parameter and the width for height parameter when calling SetPixelData.

Rotate using BitmapTransform.

The described approach of a rotation gives us basic understanding of simple transformations that can be applied on a bitmap. But in a real project we don’t need to manipulate with pixels. BitmapTransform class has a set of properties, which can modify a picture depending on our needs. I updated SaveRotateAsync to use BitmapTransform to achieve the desired result:

You might need to implement a swiping behavior in a list similar to FlipView control. In FlipView, a swiping always ends at the center of an element. Unlike it works by default in ListViewBase control, where user can see many items at once and stopping points are randomly chosen. But FlipView is not really wanted, when it’s required to display left and right items. The behavior I needed to achieve:

I also override ItemsPanel in this XAML, because I want to show items in a horizontal panel.

Example.

Take a look at the example here. Launch the app at Windows mobile emulator and hit Snap points example button. As soon as the next page is being loaded and a list with images is being shown, swipe to the second item and immediately to the first one. You will notice a bug. The first item becomes unreachable. I fixed the issue with inserting empty items in the beginning and the end of the list:

1

2

3

4

5

6

7

privatevoidInsertEmptyItems(List<Image>images)

{

images.Insert(0,Image.Empty);

images.Insert(images.Count,Image.Empty);

}

GridView.ScrollIntoView() allows to make the first not empty item logically focused:

1

2

3

4

5

6

privatevoidScrollToFirstItem()

{

ImagesList.ScrollIntoView(ImagesList.Items[1]);

}

To make the example works fine, go to HorizontalSnapPointsPage.xaml.cs and undo commented InsertEmptyItems() and ScrollToFirstItem() methods. Swiping in the list works as expected now.

After the main functionality is ready, the same steps can be applied for locales you want to support in the app. You also might need to create a service to load and access the resources. But intent of this article is to take a deeper look at the internal structure of localized resources in a package, when an app is ready to be published to the store.

With Universal Windows Platform, a new way of an app distribution was introduced. Microsoft suggests to create a bundle when your app is ready for submission to the store. Appxbundle is an archive file, which contains app packages for: x86, x64 and ARM. What is also interesting about app bundle is that allows to manage resources included into a package. Usually, an app has string resources or images with different resolutions for different locales. And for sure, when a user installs an app, he doesn’t need everything at his device. That’s exactly what app bundle helps to solve. All resources in an app bundle are packed in some way and when a user downloads an app, he gets localized resources, related to his device language settings. Thus, users from USA won’t get German resources, because they don’t need them.

This image can give you some insights about internal structure of a bundle:

Apart of the files related to the locales, there is also AppManifest file which contains metadata about the resources.

When a user installs a package distributed as not a bundle, he gets all localized resources used in the app. And that’s the main difference between a bundle distribution and the distribution used for Windows 8.1 apps.

If localized resources are downloaded respectively with a device language settings, how then programmatically apply different locales for UI? What if users want to set a different language? A language which is not the same as in device settings? That’s a tricky part of appxbundle. Even, you might not notice any issue with that when developing your app. But when try to change a language when the app is installed from a bundle, you will see that not every locale is applied properly. That’s because end device doesn’t have all files with localized resources.

The described issue can be handled in different ways. One possible solution is implemented in Bing News app. When the user chooses the app language, it asks to add chosen language to the device settings and set it as display language. Afterwards, an update will be installed by Windows. I suspect that Windows also will update the app with required resources file from the store.

The second solution is to implement custom localization and apply a resource value with bindings instead of x:Uid directive.

The third solution is to publish your app in the old way, with a package per configuration. As I mentioned before, if create a package but not a bundle, all localized resource will be included to that package. Thus, this approach gives more flexibility while can significantly increase the size of downloaded package for final users.

Once you started to distribute an app as a bundle, it won’t be possible to switch to a package per configuration. Dev center forbids an update with separated packages above appxbundle.

Actually, that’s not always forbidden. Our team had a bad experience with that. We published an update as a bundle for existing Windows 8.1 app. In other words, new Windows 10 app as an update for Windows 8.1 app. Afterwards, we figured out that localization doesn’t work as we expected. We decided to switch to a package per configuration distribution. We did that update and when submitting, it was allowed to upload three separated packages. As soon as the update became available, the users started complain about a crash when the app was launching.

That was really painful. It took significant amount of time to figured out the reason. When an update is being installed, all localized resources are being merged. Thus, the system tried to merge the resources from the installed bundle with the resources included to a new package. Such merge is not possible. And it wasn’t easy to catch the reason.

The main lesson – don’t switch from a bundle to the old way of distribution. It’s very possible that you will get some issues with that. But migrating to a bundle from the old way of distribution works well.

If we would like to build a client for Twitter, we would use scheme+host+version in every query. That’s a common part. URL builder is responsible to compose the common part with relative path and adds parameters to the resulting string.

Using Builder pattern, implies initializing an object without parameters or with few of them. The construction of the object is done during runtime. In my case, UrlBuilder has a constructor, which accepts a host string and a version.

Relative path and parameters can be added later depending on the context:

The example contains two methods. But of course, the factory can be extended depending on your needs. Personally, I create a factory per services group. For Twitter API, I would add a factory for statuses, friendships and etc.

In Windows Universal app, when user has been navigated back, the top page at the navigation stack is being re-created again. That’s because a page itself is not kept in memory, when the user navigates forward to another page.

Let’s imagine an app. The first page of the app has a list. The user can scroll the list down and when he taps a list item, he has been redirected to the item details page. When the user presses back button, the main page is appeared. But the state of the page is not preserved. The user sees the same list with initial scroll viewer position. He has to scroll again to the item he left the page.

How to improve the described scenario to make the user happy? In our example, a developer has two options:

Maintain ViewModel of the main page as Singleton and keep ScrollViewer vertical offset in the ViewModel;

Enable UI cache for the main page.

I prefer the second one.

Navigation cache mode.

Page.NavigationCacheModeis the property, which allows a page to be stored in memory if the value of the property is set to Enabled or Required. In our case, the MainPage with enabled NavigationCacheMode, will be created once. Furthermore, the details page, with enabled navigation cache, is also created once and will be reused to show details of every data item. Thus, a page with NavigationCacheMode=Enabled stays in memory even the user navigates back or forward from the page.

Loaded EventTriggerBehavior and back navigation.

XamlBehaviors is a great library. It allows to get rid of event handlers in a page class and bind event handlers with commands exposed by ViewModel at XAML level. But be aware about using EventTriggerBehavior for Loaded event together with enabled NavigationCacheMode.

Let’s assume we have MainPage in our app with navigation cache is enabled:

1

2

3

NavigationCacheMode="Enabled"

In page XAML, there is EventTriggerBehavior which executes a command when the root element has been loaded. And a button, which navigates the user to another page, when it’s been clicked:

When the page is being loaded in the first time, LoadedCommand executes as expected. But what happens, when the user goes back from another page to the MainPage? If the user navigates back, Loaded event for the root Grid fires and I expect LoadedCommand to be executed as well. As you can guess, it doesn’t work in this way. When the user navigates back, EventTriggerBehavior isattached to the root element after the element has been loaded. So, for the described case, LoadedCommand never will be triggered.

For similar scenarios, it’s better to subscribe for FrameworkElement.Loaded manually and execute a command in code behind. Either, override Page.OnNavigatedTo and call your logic from there.

You might seen similar errors when trying to bind a data item to a wrong template. The difference in my case is that the UI looked well, without any visible issues. I prepared a test project to reproduce the bug. The code is at github.

The test application shows some heterogeneous data in a ListView. My test data is three objects: Cookie, Milk and Orange.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

classCookie

{

publicintPieces{get;set;}

publicoverridestringToString()

{

return$"Cookie {Pieces}";

}

}

classMilk

{

publicintLiters{get;set;}

publicoverridestringToString()

{

return$"Milk {Liters}";

}

}

classOrange

{

publicintWeight{get;set;}

publicoverridestringToString()

{

return$"Orange {Weight}";

}

}

There are two lists in the app. The lists have various approaches of applying a DataTemplate for an ItemContainer. For the left ListView, I set the ListView.ItemContainerSelector property to an instance of my custom DataTemlateSelector:

As you noticed, I override DataTemplateSelector.SelectTemplateCoreto choose a template for a data item. If you scroll down the left list, you immediately will see the errors in Debug Output window of VisualStudio. The fact, that the errors are appearing when scrolling the list, made me think that the realization of items works wrong. And most probably the bug in ProductTemplateSelector. If uncomment the debug lines in ProductTemplateSelector.SelectTemplateCore method, the output will show something interesting:

It says that an ItemContainer is being reused for a data item and DataTemplate.SelectTemplateCore is being executed twice for the same data item.

In fact, DataTemplateSelector has two versions of SelectTemplateCore:

1

2

3

4

5

6

7

8

9

10

protectedvirtualDataTemplate SelectTemplateCore(

objectitem

)

protectedvirtualDataTemplate SelectTemplateCore(

objectitem,

DependencyObject container

)

And which version a developer needs to utilize depends on underlying ItemsPanel. If you use GridView or ListView with ItemsStackPanel or with ItemsWrapGrid then SelectTemplateCore(Object) needs to be overriden. By default, the underlaying panel for ListView and GridView is ItemsStackPanel. But if ItemsPanel is VirtualizingStackPanel or WrapGrid then SelectTemplateCore(Object, DependencyObject) should be implemented. The rule applies to any ItemsControl.

I override the wrong version of SelectTemplateCore in my ProductTemplateSelector. That’s the origin of the error. Uncomment ProductTemplateSelector.SelectTemplateCore(Object) in the example, run the app. The list now works smoothly.

What I also want to show you is how to apply a DataTemplate for an ItemContainer without using ListView.ItemContainerSelector. Starting from Windows 10, ListView and GridView controls have a new ListViewBase.ChoosingItemContainer event.

In the test app, the ListView with custom implementation of ChoosingItemContainer is shown at the right part of the MainPage. And the handler for the event is very simple:

Needless to say, that ChoosingItemContainer gives better control when creating an item container. DataTemplateSelector is very simple to use and it does what it does. But when it requires to gain some performance benefits, then the best way is to implement a handler for ChoosingItemContainer event. You can also get more ideas about the usage of the new event from MSDN.