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!