Saturday, October 21, 2017

UWP Tip #8 - UWP Community Toolkit - Part 6, Using the VisualTree and LogicalTree UI Helpers

Welcome back to the UWP Community Toolkit series. Previous Tips in the UWP Community Toolkit series:
Introduction
This tip will continue exploring the Code Helpers that we started looking at in Part 3. There are only a few types of helpers remaining, and today we will examine the collection of available VisualTree and LogicalTree UI extension methods.
VisualTree Extensions
The VisualTree extension methods extend and simplify the built-in UI element navigation methods of the framework. There are currently five methods available to use in the toolkit.
  • FindDescendantByName(elementName) - Navigates down the visual tree until an element with the provided name is found.
  • FindDescendant<T>() - Navigates down the visual tree and returns the first element for the given type.
  • FindDescendants<T>() - Returns an IEnumerable of all descendant elements of the given type.
  • FindAscendantByName(elementName) - Navigates up the visual tree until an element with the provided name is found.
  • FindAscendant<T>() - Navigates up the visual tree and returns the first element for the given type.
Here is an example of the use of each method to retrieve UI elements from your visual tree.
public void ProcessVisualUiElements()
{
    var listControl = mainGrid.FindDescendantByName("resultList");
    listControl = mainGrid.FindDescendant<ListView>();
    listControl.MaxWidth = 500;
    foreach (var item in mainGrid.FindDescendants<ListViewItem>())
    {
        item.IsEnabled = false;
    }
    var gridControl = resultList.FindAscendantByName("mainGrid");
    gridControl = resultList.FindAscendant<Grid>();
    gridControl.Margin = new Thickness() { Bottom = 2, Left = 2, Right = 2, Top = 4 };
}

Most UWP developers will probably use the FindAscendant/FindDescendant methods using the type of element to find as we try to avoid naming our UI elements.
LogicalTree Extensions
The LogicalTree extensions are very similar but they operate over logical elements, ignoring certain containers and style elements only found in the visual tree. Not having to rely on knowing if the elements have been rendered yet before finding them can be an advantage of this method also.
The set of methods available mirror those for the visual tree with one additional method to find an element's content control.
  • FindChildByName(elementName)
  • FindChild<T>()
  • FindChildren<T>()
  • FindParentByName(elementName)
  • FindParent<T>()
  • GetContentControl()
The sample code also mirrors the previous sample.
public void ProcessLogicalUiElements()
{
    var listControl = mainGrid.FindChildByName("resultList");
   
    listControl = mainGrid.FindChild<ListView>();
   
    foreach (var item in resultList.FindChildren<ListViewItem>())
    {
        item.IsEnabled = true;
    }
   
    var gridControl = resultList.FindParentByName("mainGrid");
   
    gridControl = resultList.FindParent<Grid>();
   
    var searchContent = searchTextBox.GetContentControl();
}

Wrap-Up
That's all for today's helpers! They're very straightforward to use and can save quite a bit of manually traversing the visual and logical trees to find a target element. Check back as next time we will finish up the helpers provided by the UWP Community Toolkit.
Happy coding!

del.icio.us Tags: ,,








Thursday, October 12, 2017

UWP News - UWP in FCU Supports .NET Standard 2.0

Big news this week for UWP developers. If your app is targeting Windows 10.0.16299 (the Fall Creators Update), you can now access ~20,000 APIs that were added as part of .NET Standard 2.0.

The announcement was made during Windows Developer Day on Tuesday, and a .NET Blog post by Rich Lander and Immo Landwerth dives into some of the details.

In order to use .NET Standard 2.0 in UWP, you need to target Fall Creators Update (FCU) as the minimum version of your UWP project. That’s because .NET Standard 2.0 contains many APIs that require FCU to make them work in the context of the UWP execution environment, specifically AppContainer.

To get started, go upgrade to the Fall Creators Update, get the new Windows SDK and the new build of Visual Studio 2017 (v15.4). Get started building new UWP apps or updating your existing apps to support the FCU features and .NET Standard 2.0. Microsoft is offering some great prizes in a new contest to encourage Windows developers to target the FCU, including a Surface Studio. Get the contest details here.

Landwerth has also updated his .NET Standard Selector website to include .NET Standard and UWP. If you are unsure of which platforms are supported by each version of .NET Standard, check out this handy reference.

Happy coding!

Friday, September 29, 2017

UWP Tip #7 - UWP Community Toolkit - Part 5, Using the Streams Code Helper

Welcome back to the UWP Community Toolkit series. Previous Tips in the UWP Community Toolkit series:

Introduction

This tip will continue exploring the Code Helpers that we started looking at in Part 3. There are three types of helpers remaining, and today we will examine the StreamHelper class.

Purpose

The StreamHelper class contains methods to read files from a stream via local files or via a network stream. There is also a helper method to read data from an http source and write it directly to a local file. There are also some helper methods to check if files and folders exist for a given name and path.

Let's look at a few of the method signatures:

  • GetHttpStreamAsync(System.Uri uri) - Gets a stream from an HTTP request.
  • IsLocalFileExistsAsync(System.String fileName) - Checks if a local files exists in the application's folder.
  • IsLocalCacheFileExistsAsync(System.String fileName) - Checks if a local file exists in the cache folder.
  • ReadTextAsync(Windows.Storage.Streams.IRandomAccessStream stream,System.Text.Encoding encoding) - Takes a stream and reads it to a returned string.

Example

In this short example, we are going to create a StreamService for our project that implements an IStreamService interface for testability. Although the lack of an interface for the toolkit's StreamHelper makes it a little tricky to mock this for our tests. We'll leave this for another day or perhaps an issue to be filed on their GitHub.

The StreamService has two methods, one for getting a string back from and HTTP call and another to get one from reading a file in the local cache.

public class StreamService : IStreamService
{
    public async Task<string> GetStringFromUrlAsync(Uri source)
    {
        using (var stream = await StreamHelper.GetHttpStreamAsync(source))
        {
            return await stream.ReadTextAsync();
        }
    }
     public async Task<string> GetStringFromLocalCacheAsync(string fileName)
    {
        using (var stream = await StreamHelper.GetLocalCacheFileStreamAsync(fileName, Windows.Storage.FileAccessMode.Read))
        {
            return await stream.ReadTextAsync();
         }
    }
}

Everything is wrapped up with only strings and a Uri in and out, keeping the external dependency out of our ViewModels. To check out all of the available helper methods in the StreamHelper class, you can visit the API documentation here.

Wrap-Up

Only two helper types to go. Next time we will continue with the VisualTreeExtensions code helper in the UWP Community Toolkit.

Happy coding!

 

del.icio.us Tags: ,

Tuesday, September 26, 2017

UWP App Tips Recommended Video - Bringing Your WinForms/WPF Investments Forwards with UWP/.NET Standard 2.0

The UWP Community Toolkit tips series will continue later this week. Today's post is a video that I recommend to all Windows developers.

Last week, Microsoft's Channel 9 hosted the online virtual 3-day conference, .NET Conf. The conference covered topics ranging from ASP.NET Core to Xamarin to Visual Studio tooling and lots more. I recommend you go check out all of the sessions to see what interests you. Last I checked, there were 45 videos available for the conference.

The one video I wanted to call out for UWP and all other Windows developers is titled Bringing Your WinForms/WPF Investments Forwards with UWP/.NET Standard 2.0. This session was presented by Chris Barker and Daniel Jacobson is described as:

.NET Standard 2.0 with Visual Studio 2017 makes it even easier to bring your WinForms/WPF investments to the Universal Windows Platform - enabling you to reach new audiences and easily deliver a modern user experience, all whilst continuing to service your existing user base. This session will introduce you to the benefits of .NET Standard 2.0, and walk you through the process for extending the reach of your app efficiently.
The hosts are very engaging and I think this session is yet another indicator that Microsoft is standing firm on their position that UWP is the way forward for all Windows app development.While large legacy code bases on WinForms and WPF may not ever migrate to UWP. I work for a company with a mix of WPF, WinForms and MFC which is unlikely to take this path. However, it is a real possibility for many WPF and some WinForms applications, especially those which are smaller non-enterprise applications.

Enjoy the video and don't forget to peruse the rest of them on Channel 9!


Friday, September 22, 2017

UWP Tip #6 - UWP Community Toolkit - Part 4, Leveraging the StorageFiles and Storage Code Helpers

Welcome back to the UWP Community Toolkit series. You'll have to excuse the delay between posts as TechBash 2017 has been monopolizing my free time this month.

Previous Tips in the UWP Community Toolkit series:

Introduction

This tip will continue exploring the Code Helpers that we started looking at in Part 3. There are five types of helpers remaining, and today we'll look at the StorageFileHelper and Storage helpers.

StorageFiles

The StorageFileHelper utility class has helper methods for reading from and writing to disk. There are method overloads to read and write both text and binary data to a file either directly to the local storage folder or to given folderId and/or folderName. Some overloads for writing take a CreationCollisionOptions parameter to decide how to handle conflicts during file or folder creation. All StorageFile operations are async.

Here is a simple example of simple read and write service methods that wrap calls to the StorageFileHelper methods that use the user's local storage.

 public async Task WriteUserData(string data, string fileName)
{
    await StorageFileHelper.WriteTextToLocalFileAsync(data, fileName);
}

public async Task<string> ReadUserData(string fileName)
{
    return await StorageFileHelper.ReadTextFromLocalFileAsync(fileName);
}

Storage

The StorageService, not to be confused with the previous StorageFileHelper, is for reading and writing objects within your application. The objects can be read and written locally or you can choose to roam the data across all the user's devices. This selection is made by using either a LocalObjectStorageHelper or a RoamingObjectStorageHelper. Makes sense.

Let's say you had a health care application of some kind and you wanted to save an object containing the currently selected clinic's information.

 public class Clinic : IClinic
{
    public string Name { get; set; }
    public string Location { get; set; }
    public int NumberOfBeds { get; set; }
    public ClinicType Type { get; set; }
}

We want to take this and persist it for the current device. So, we'll create some service methods to read and write the object local to the current device.

    public class StorageService
    {
        private LocalObjectStorageHelper _localStorageHelper = new LocalObjectStorageHelper();

        public async Task SaveClinic(IClinic clinic, string key)
        {
            await _localStorageHelper.SaveFileAsync(key, clinic);
        }

        public async Task<IClinic> ReadClinic(string key)
        {
            return await _localStorageHelper.ReadFileAsync<IClinic>(key);
        }
    }

That's it. We've wrapped the methods to read and write and only need to deal with our own interfaces in and out. If you wrap this service class in an interface and inject the helper itself, it will be nicely abstracted for testability. You can use these service methods from any of the existing ViewModels in your UWP app.

Wrap-Up

Next time we will continue with the Code Helpers in the UWP Community Toolkit. The Streams helper is up next.

Happy coding!

Wednesday, August 30, 2017

UWP News - UWP Community Toolkit 2.0 has been released

This is just a quick break from the UWP Tips to let you know that the UWP Community Toolkit 2.0 has been released by Microsoft. There are a bunch of changes for developers and designers, including enhancements to support the Fluent Design System coming in the Windows 10 Fall Creators Update.

Go check out this post on the Windows blog for all the details.

Today, the UWP Community Toolkit graduates to version 2.0 and sets the stage for future releases.
There have been seven releases since the UWP Community Toolkit was first introduced exactly one year ago and version 2.0 is the first major and largest update to date. The developer community has worked enthusiastically to build something that is used by thousands of developers every month. Today, there are over 100 contributors, and developers have downloaded the packages over 250,000 times. This would not be possible without the strength of the community – Thank You!

If you want to skip the announcement and get coding, you can grab the latest on NuGet or check it out on GitHub.

Happy coding!

Thursday, August 24, 2017

UWP Tip #5 - UWP Community Toolkit - Part 3, Leveraging Code Helpers (Color, Connection, Converters and ImageCache)

Previous Tips in the UWP Community Toolkit series:

Introduction

In part 3 in this mini-series on the UWP Community Toolkit, we will get an overview of four of the available groups of Code Helpers in the toolkit.

Colors

The Colors helper methods provide a few simple conversions when working with colors in your UWP app.

ToColor() - Take a string, which can be an HTML color, Alpha code or string representation of a Windows.UI.Color, and it returns a Windows.UI.Color.

ToHex() - Takes a Windows.UI.Color and returns the hexadecimal value of that color (string).

ToInt() - Takes a Windows.UI.Color and returns an ARGB structure as an integer.

ToHsl() - Takes a Windows.UI.Color and returns an HslColor.

ToHsv() - Takes a Windows.UI.Color and returns an HsvColor object.

FromHsl() and FromHsv() - Just the opposite of the last two helper methods.

Connection

The ConnectionHelper currently expose two (self-explanatory) Boolean properties;

  • IsInternetOnMeteredConnection
  • IsInternetAvailable

Converters

The toolkit provides four Converters in the current version of the NuGet package.

BoolToVisibiltyConverter - I think we have all written this one a few times before, or perhaps leveraged one from another UWP or WPF library. It converts a Boolean property from your DataContext to a Visibility enum value.

CollectionVisibilityConverter - This converter will return Visible if a collection is null or empty. This can be useful to display a message when no results are available for a list.

StringFormatConverter - Converts an object to a string and takes an option parameter to use when the converter calls string.Format(object, optionalParameter).

StringVisibilityConverter - Similar to the CollectionVisibilityConverter, this converter returns Visible if a string is null or string.Empty.

ImageCache

The ImageCache will help you store images in a cache in temporary local storage in an async manner. Available methods and properties include:

InitializeAsync() - Sets up the cache with a folder location and a name for the cache folder.

ClearAsync() - Clears the cache. An overload is also provided to clear cache contents based on a TimeSpan.

PreCacheAsync() - Pre-caches a supplied image from the online Uri.

GetFromCacheAsync() - Fetches an image from the cache. If the image is no longer in the cache (or never was), it will be fetched from the supplied Uri.

CacheDuration - Sets the duration (TimeSpan) to store images in the cache.

MaxMemoryCacheCount - The maximum number of images to store in the cache instance.

Wrap-Up

There are dozens of great helper methods and properties available in the UWP Community Toolkit. We're just getting started with the review of what's available. Next time, we'll examine the rest of the helper categories. Go check them all out and add the NuGet package to your UWP project today!

Happy coding!

 

del.icio.us Tags: ,

Sunday, August 6, 2017

UWP Tip #4 - UWP Community Toolkit - Part 2, Consuming the Services

Previous Tips in the UWP Community Toolkit series:
In this tip, we are going to look at the services provided by the UWP Community Toolkit. Currently, there are three services exposed through the toolkit:
  • Bing - Add Bing search capability to your Windows app.
  • Facebook - Read a user's Facebook data and post for them.
  • Twitter - Read, search and post on Twitter easily.
To get started with any of these services, add the "Microsoft.Toolkit.Uwp.Services" NuGet package to your UWP application in Visual Studio.


I created a simple app that can use Bing to do a regular search or news search and display the title, summary and url of the search results in a ListView with minimal formatting. The user can then select one of the results and tweet the title + url to their followers.

The app uses The UWP Community Toolkit for services and MVVMLight to add MVVM capabilities. Let's start by taking a look at the two services classes added to wrap the Toolkit's Bing and Twitter service calls.

public class SearchService : ISearchService
{
    public async Task<List<IQueryResult>> Search(string searchText, bool searchNews)
    {
        var searchConfig = new BingSearchConfig
        {
            Country = BingCountry.UnitedStates,
            Language = BingLanguage.English,
            Query = searchText,
            QueryType = searchNews ? BingQueryType.News : BingQueryType.Search
        };
        var results = await BingService.Instance.RequestAsync(searchConfig, 50);         var queryResults = new List<IQueryResult>();
        foreach (var x in results)         {             queryResults.Add(new QueryResult             {                 Title = x.Title,                 Summary = x.Summary,                 Link = x.Link             });         }
        return queryResults;     } }
public class LocalTwitterService : ILocalTwitterService {     private string _key = "";  // removed (add your key here)     private string _secret = "";  // removed (add your secret here)     private string _callbackUri = "";  // removed (add your uri here)
    public async Task SendTweetAsync(string title, string url)     {         // Initialize service         TwitterService.Instance.Initialize(_key, _secret, _callbackUri);
        // Login to Twitter         if (!await TwitterService.Instance.LoginAsync())         {             return;         }                 // Post a tweet         await TwitterService.Instance.TweetStatusAsync($"shared: {title} {url}");     } }

The services are consumed in the MainViewModel after being injected into the VM's constructor. There are Search and Tweet It buttons on the UI which invoke each command method in the VM.

public ICommand SearchCommand { get; private set; }
public ICommand SendTweetCommand { get; private set; }
public async void Search() {     SelectedResult = null;     RaisePropertyChanged(nameof(SelectedResult));
    QueryResults.Clear();
    var results = await _searchService.Search(SearchText, SearchNews);
    foreach (var result in results)     {         QueryResults.Add(result);     } }
public async void SendTweet() {     await _twitterService.SendTweetAsync(SelectedResult.Title, SelectedResult.Link); }

The SearchText property contains the search terms entered by the user and SearchNews is a boolean property bound to a checkbox on the UI. QueryResults is an ObservableCollection of IQueryResult, a class holding the Title, Summary and Link of each search result, and SelectedResult is bound to the SelectedItem on the ListView.

The view for the main page consists of a Grid with three rows and three columns and these contents:

<TextBox Grid.Column="0" Margin="4" Text="{Binding SearchText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<Button Grid.Column="1" Content="Search" Margin="0,4,0,4" Command="{Binding SearchCommand}"/>
<CheckBox Content="Search News" Grid.Column="2" IsChecked="{Binding SearchNews, Mode=TwoWay}"/>
<ListView Grid.Row="1" Grid.ColumnSpan="3" Margin="4"             ItemsSource="{Binding QueryResults}"             SelectedItem="{Binding SelectedResult, Mode=TwoWay}">     <ListView.ItemTemplate>         <DataTemplate>             <Grid Margin="4">                 <StackPanel VerticalAlignment="Top">                     <TextBlock Text="{Binding Title}"/>                     <TextBlock Text="{Binding Summary}" TextWrapping="Wrap"/>                     <TextBlock Text="{Binding Link}"/>                 </StackPanel>             </Grid>         </DataTemplate>     </ListView.ItemTemplate> </ListView>
<Button Grid.Row="2" Grid.Column="2" Content="Tweet It!"         Margin="4" HorizontalAlignment="Stretch"         Command="{Binding SendTweetCommand}"/>

Here is a look at the running application with one of the search results selected and ready to tweet.


The entire application consists of very little code, and could contain even less if you were content to wire up events directly in the main view's code behind without any service classes wrapping the Toolkit services or ViewModels abstracting logic from the UI. I feel it is best to practice writing decoupled, testable code even in the simplest of sample applications.

Go check out the latest drop of the UWP Community Toolkit online or via NuGet today. Happy coding!

Tuesday, July 18, 2017

UWP Tip #3 - UWP Community Toolkit - Part 1, What's in the Box?

Once upon a time, Microsoft released a set of free controls for WPF developers. It was called the WPF Toolkit. It contained components such as DataGrid, DatePicker, Calendar, AutoCompleteBox, and a Chart control. Today's XAML developer would consider these to be basics that would be in the box with their framework. At the time, we saw them as a saving grace. The Extended WPF Toolkit took it a step further, but that's a tale for another blog.

Today's UWP offers these types of controls and much more with File-->New Project-->Blank App. Accordingly, today's toolkit delivers richer, more advanced tools.

Last August, hot on the heels of the Windows 10 Anniversary Update, Microsoft announced the UWP Community Toolkit. Earlier this month, the UWP Community Toolkit v1.5 was released. Unlike the WPF Toolkit of yesterday, this toolkit is about more than UI controls. Sure, it has controls. It has some pretty useful controls:
  • AdaptiveGridView - A grid to better handle today's wide variety of form factors.
  • HeaderedTextBlock - A read-only header/text combination.
  • HamburgerMenu - This has become a staple of modern app design.
  • ImageEX - Loads images async with a loading indicator, plus support for caching. My favorite control in the current collection.
  • RotatorTile - Similar to a live tile within your app.
  • PullToRefreshListView - All the cool kids with iOS love Pull to Refresh. Now your users will too.
  • RadialGauge - Everyone love a gauge control. This one is just what you expect.
  • RangeSelecter - A slider with two points for selecting a value range.
  • SlideableListItem - Slide your list items left or right to take actions on them. This has become a more common UX, especially in mobile email clients.
  • BladeControl - You know the Azure Portal? Those blade that slide back and forth as you navigate through sections. Yes, you can create that same experience in your apps now.
In addition to controls, the toolkit provides:
  • Code Helpers - A trove of helper methods for things like storage, streams, color handling, and converters for data binding.
  • Services - Get started with social and search services in your app.
  • Animations - Quickly add cool visual effects to your application.
  • Notifications - Live Tiles and Toast notifications created with ease.
Each part of the toolkit can be downloaded to your project via its NuGet Package, making it easy to pick and choose which parts of the toolkit you'll want to leverage in your app without adding unnecessary bloat. To get started, just manage the NuGet packages for your UWP project and search for "Microsoft.Toolkit.UWP":




Each package's description has enough information to easily identify which of them you will want to download to your project. You'll get any other dependent packages also… because Nuget

The entire UWP Community Toolkit is Open Source. If there is something in the toolkit that needs a fix or enhancement, add an issue, fork it, create a pull request. You know the drill by now.

Next time, in UWP Tip #4, we will start building an application with the UWP Community Toolkit. In the coming weeks, I will examine the different parts of the toolkit over a series of posts.

In the meantime, go check it out for yourself!

Sunday, July 9, 2017

UWP Tip #2 - Windows Template Studio - Examining the Project

Introduction

In Tip #1, I created a new UWP project with a template from Windows Template Studio v1.1. The app is a Navigation Pane style project that uses MVVMLight and contains Web Views to display three different websites.

Let's take a look at a few aspects of the generated project.

NuGet Packages

Besides the basic UWP NuGet package, three other packages were added to my project when it was created.

Views

Views were created for the application's shell, the main page which is generated without any content, and my three Web Views.
  • ShellPage.xaml
  • MainPage.xaml
  • MorningDewPage.xaml
  • UWPTipsPage.xaml
  • WPFTipsPage.xaml
The ShellPage contains the Hamburger menu & Navigation Tree on the left side and the content panel on the right side to host each of other views in the project.

Each web view contains some style code for in the Page.Resources for styling the browser buttons. If you have multiple web views, this XAML could be centralized and reused across your pages. There is also some code for handling the loading behaviors, visibility, and the WebView (Windows.UI.Xaml.Controls.WebView) itself.

The MainPage is essentially empty with the exception of some Xaml to handle the VisualStates. I added a couple of TextBlocks with a welcome message and some information about navigating to the other pages.

ViewModels

There are ViewModels corresponding to each view listed above. There is another for ShellNavigationItem. This facilitates handling multiple pages in the navigation app without hard-coding them in the Shell's view somewhere. There is also a ViewModelLocator class, which will be familiar to anyone who has used MVVMLight. This answer on StackOverflow does a great job of explaining its purpose.

The ShellViewModel uses the ShellNavigationItem and a NavigationServiceEx to switch between the views of its main content panel.
private void Navigate(object item)
{
    var navigationItem = item as ShellNavigationItem;
    if (navigationItem != null)
    {
        NavigationService.Navigate(navigationItem.ViewModelName);
    }
}
Most of the code in the ViewModels for each web view is dedicated to handling. I would recommend refactoring most of this code out to a common base class if you are going to be working with more than one or two web views in a project. Much of the logic is centered around handling navigation between websites and web pages within the WebView control: browsing forward/back, retry, refresh, etc.

Services and Helpers

There are two service classes in the project, ActivationService and NavigationServiceEx. Let's start with the NavigationServiceEx used by the Shell. Here's the class diagram of this service.


It contains all you need to browse between your child views, including browser-style back/forward functionality.

The ActivationService encapsulates our app's activation behavior and its back stack in Windows, working with the NavigationServiceEx for this.


Wrap-Up

The project I generated with Windows Template Studio, created a great starting point for application that can be used to navigate a few different websites. If you create something similar, I would recommend some refactoring to reduce code duplication between Views and ViewModels of the same type. This will lead to much greater maintainability moving forward. Otherwise, it's a really solid way to get started on your next project.

Happy coding!

Sunday, July 2, 2017

UWP Tip #1 - Build Your First App with Windows Template Studio

Welcome to the Tip #1 here on UWP Tips!

Do you have an idea for an relatively simple app but just don't have the time to get it off the ground? Maybe you have a web site or blog, and you would like to add an app that surfaces the existing web UI. Even the simplest of apps requires a great deal of infrastructure code be built up front, right?

Windows Template Studio

Earlier this year, the WinDev team at Microsoft unveiled Windows Template Studio, a Visual Studio extension that makes UWP app development accessible to more developers.



After installing the extension, select the new project type for Windows Template Studio (Universal Windows) found under Windows Universal. This will start a wizard-style experience to select the frameworks, pages and features to be added to your application.


The Wizard



I elected to create a Navigation Pane project using MVVMLight instead of the code-behind model for my app. I also added three Web View pages for my three blogs, named UWPTips, WPFTips and MorningDew.

Upon completing the wizard, the solution is loaded in Visual Studio 2017. Each view, in addition to the Main and Shell views, is generated along with a corresponding ViewModel.



Each of my Web View ViewModels has a constant defined for the initial web page to load into the View.
private const string defaultUrl = "https://developer.microsoft.com/en-us/windows/apps";
Change each of these to the desired starting web Url for that View.
private const string defaultUrl = "http://www.uwpapp.tips";
I made one additional change to the generated project. In the PopulateNavItems() method of ShellViewModel, I updated the symbols used as icons in the left navigation bar for each page. By default, each was using Symbol.Document. I changed this to make each page's symbol unique and more identifiable.
_primaryItems.Add(new ShellNavigationItem("Shell_Main".GetLocalized(), Symbol.Home, typeof(MainViewModel).FullName));
_primaryItems.Add(new ShellNavigationItem("Shell_UWPTips".GetLocalized(), Symbol.Pictures, typeof(UWPTipsViewModel).FullName));
_primaryItems.Add(new ShellNavigationItem("Shell_WPFTips".GetLocalized(), Symbol.PreviewLink, typeof(WPFTipsViewModel).FullName));
_primaryItems.Add(new ShellNavigationItem("Shell_MorningDew".GetLocalized(), Symbol.Link, typeof(MorningDewViewModel).FullName));
The items in the Windows.UI.Xaml.Controls.Symbol enum correspond to glyphs from the Segoe MDL2 Assets font. More information is available on Microsoft Docs.

Here is a look at the app running on Windows 10 with the Creators Update. The left navigation hamburger menu has been expanded to reveal the page names, otherwise only the glyph icons appear. The WPFTips page has rendered the current content of www.wpf.tips.


The status bar area of each web view page contains basic navigation buttons for back, forward and reload plus a button to open the current page in your default browser. These web views are hosted in an embedded Microsoft Edge browser control. While an app that hosts three blog sites may not be a worthy addition to the Store, it could be made more useful by displaying individual blog posts in a 'reading mode' with sidebars, headers and footers from the sites hidden. This application style might be even more useful hosting pages containing document repositories or other online libraries.

Windows Template Studio v1.1 was just released last month, containing a number of additions, enhancements and fixes. The entire project is open source, with the source available on GitHub. Go check it out today and build something awesome!

Next time, in Tip #2, we will take a closer look at the code generated for my AppTips project and what is going on under the covers to navigate around the app.

Monday, June 26, 2017

Welcome to UWP Tips - Quick tips and tricks for UWP app developers!

Hello!

Welcome to my latest creation. I hope you're already following The Morning Dew and WPF Tips. This new blog will follow a similar pattern to WPF Tips, but will focus on developing Windows Apps with UWP and someday soon XAML Standard too.

Expect to see new tips posted 2 to 3 times per month. I will share these links on the Dew Drop, so if you already follow me there, watch for links in the "XAML, UWP & Xamarin" section.

Thanks for reading and happy coding!


Alvin


del.icio.us Tags: ,,,