{"id":432,"date":"2021-10-20T00:43:59","date_gmt":"2021-10-20T07:43:59","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/ifdef-windows\/?p=432"},"modified":"2021-10-20T09:46:20","modified_gmt":"2021-10-20T16:46:20","slug":"building-your-first-uwp-application","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/ifdef-windows\/building-your-first-uwp-application\/","title":{"rendered":"Building Your First UWP Application"},"content":{"rendered":"<h2>What&#8217;s the deal with UWP?<\/h2>\n<p>Universal Windows Platform is all about developing apps that are not only for Windows, but look, feel, and interact like they <em>should<\/em> be on Windows. Any device that runs Windows can run a UWP application, and UWP allows for integration and styling that really makes your application feel like it belongs on Windows.<\/p>\n<p>One of my favorite UWP applications is <a href=\"https:\/\/github.com\/jenius-apps\/ambie\">Ambie<\/a>, an open source, white-noise sound application built by one of my colleagues, <a href=\"https:\/\/twitter.com\/kid_jenius\">Daniel Paulino<\/a>:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/ifdef-windows\/wp-content\/uploads\/sites\/61\/2021\/10\/Ambie.png\" alt=\"\" \/><\/p>\n<p>Ambie is an awesome app, so let&#8217;s try to imitate it!<\/p>\n<h2>UWP Animal Soundboard<\/h2>\n<p>What if instead of soothing atmospheric noises and a level of iterative polish, Ambie had obnoxious animal noises and was built in 30 minutes?<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/ifdef-windows\/wp-content\/uploads\/sites\/61\/2021\/10\/AnimalSoundboard.png\" alt=\"\" \/><\/p>\n<p>As simple as this demo app is, it shows some cool things you can do right away with UWP:<\/p>\n<ul>\n<li>Working with different types of media (in our case, audio, but it&#8217;s just as easy to get started with video, photo, etc.)<\/li>\n<li>Speech Synthesis! Just one example of a neat API included with UWP<\/li>\n<li>Simple, easy-to-use, and consistent UI controls, especially if you&#8217;re using <a href=\"https:\/\/docs.microsoft.com\/en-us\/windows\/apps\/winui\/winui2\/getting-started\">WinUI<\/a><\/li>\n<li>Templated\/dynamic UI that changes through user interaction. You can add as many monkey buttons as you want to this UI, just keep clicking!<\/li>\n<\/ul>\n<h2>Getting Started<\/h2>\n<p>Before we&#8217;re ready to crash course through making our soundboard, we have to get a few things set up.<\/p>\n<h3>Setting Up Your Development Environment<\/h3>\n<p>If you&#8217;re not on a Windows 10\/11 machine, you can download a VM with an already set up development environment <a href=\"https:\/\/aka.ms\/win-dev\/student\/vm\">here.<\/a><\/p>\n<p>To setup the dev environment on your Windows 10\/11 machine, let&#8217;s download and set up Visual Studio. You can follow a guide to get set up on Windows <a href=\"https:\/\/docs.microsoft.com\/en-us\/windows\/apps\/windows-app-sdk\/set-up-your-development-environment?tabs=stable\">here.<\/a><\/p>\n<h3>Creating a Blank UWP App<\/h3>\n<p>Once you have Visual Studio installed, go ahead and launch it. At the start screen, select &#8220;Create a new project.&#8221;<\/p>\n<p>This will take you to a list of templates, go ahead and search for &#8220;UWP&#8221; and then select &#8220;Blank App (Universal Windows).&#8221;<\/p>\n<p>Now go ahead and create your project!<\/p>\n<h3>Resources<\/h3>\n<p>If you&#8217;re brand new to UWP and XAML, I highly recommend checking out this <a href=\"https:\/\/aka.ms\/win-dev\/student\/osu\/uwp\/sample\/getting-started-uwp\">Getting Started With UWP<\/a> guide. It will walk you through how to get started building UWP applications.<\/p>\n<p>Additionally, you can check out the <a href=\"https:\/\/aka.ms\/win-dev\/student\/osu\/uwp\/sample\">Github repository<\/a> for this project. It contains all of the code, split out into different parts and commented thoroughly.<\/p>\n<p>Now, let&#8217;s hop into the specifics of how this app was built.<\/p>\n<h2>So what makes this soundboard tick?<\/h2>\n<p>A Visual Studio UWP application comes with a whole set of files that allows your application to be installed and launched properly from the get go, but for now, you can find all of the code we are covering in just two files:<\/p>\n<ul>\n<li><strong>MainPage.xaml<\/strong>: This is a XAML file where we will define all of our UI elements, called &#8220;controls&#8221;, that will make up the visual layer of our application.<\/li>\n<li><strong>MainPage.xaml.cs<\/strong>: This is the C# code-behind file where we will put all the logic that lets us interact with our application.<\/li>\n<\/ul>\n<p>Together, these two files make up our <code>MainPage<\/code> class. When you run your app (by clicking the little green arrow at the top of Visual Studio), it will automatically navigate to this page.<\/p>\n<p>Let&#8217;s take a look at the core elements that make up the MainPage of our Soundboard app:<\/p>\n<p>First, in <strong>MainPage.xaml<\/strong>, we&#8217;re using GridView control that will dynamically display our sounds:<\/p>\n<pre><code class=\"language-xml\">&lt;GridView x:Name=\"SoundView\"\r\n    ItemsSource=\"{x:Bind Sounds}\"\r\n    ItemTemplate=\"{StaticResource SoundTemplate}\"\r\n    IsItemClickEnabled=\"True\"\r\n    ItemClick=\"SoundItemClick\"\r\n    SelectionMode=\"Single\"\/&gt;<\/code><\/pre>\n<p>GridView controls have an <code>ItemsSource<\/code> property that allows us to send it a whole collection of items to display. Our GridView&#8217;s <code>ItemSource<\/code> is bound to an <code>ObservableCollection<\/code> that&#8217;s declared in our code-behind <strong>MainPage.xaml.cs<\/strong> file:<\/p>\n<pre><code class=\"language-csharp\">public ObservableCollection&lt;SoundItem&gt; Sounds { get; set; }<\/code><\/pre>\n<p><code>ObservableCollections<\/code> are &#8220;observable&#8221; by the UI, that is, if the collection changes, so will the UI. Awesome! Our <code>ObservableCollection<\/code> is a collection of <code>SoundItems<\/code>:<\/p>\n<pre><code class=\"language-csharp\">public class SoundItem\r\n{\r\n    public string AudioFilename { get; set; }\r\n    public string PreviewText { get; set; }\r\n    public string TextToSpeech { get; set; }\r\n\r\n    public SoundItem(string audio, string prev, string tts)\r\n    {\r\n        this.AudioFilename = audio;\r\n        this.PreviewText = prev;\r\n        this.TextToSpeech = tts;\r\n    }\r\n}<\/code><\/pre>\n<p>These <code>SoundItem<\/code> objects store the data that will be consumed by our GridView to display our sound items. But wait, how does it know <em>how<\/em> to display them? That&#8217;s where we provide a <code>DataTemplate<\/code> to our GridViews <code>ItemTemplate<\/code> property:<\/p>\n<pre><code class=\"language-xml\">&lt;Page.Resources&gt;\r\n    &lt;DataTemplate x:Key=\"SoundTemplate\" x:DataType=\"local:SoundItem\"&gt;\r\n        &lt;Border  Background=\"White\" Height=\"200\" Width=\"200\" Margin=\"10,10,10,10\" CornerRadius=\"30\"&gt;\r\n            &lt;TextBlock FontSize=\"50\" VerticalAlignment=\"Center\" HorizontalAlignment=\"Center\" Text=\"{x:Bind PreviewText}\"\/&gt;\r\n        &lt;\/Border&gt;\r\n    &lt;\/DataTemplate&gt;\r\n&lt;\/Page.Resources&gt;        <\/code><\/pre>\n<p>Great, we have the look of our soundboard, but now we need some functionality. Let&#8217;s add a click listener function to our GridView&#8217;s <code>ItemClick<\/code> property:<\/p>\n<pre><code class=\"language-csharp\">private void SoundItemClick(object sender, ItemClickEventArgs e)\r\n{\r\n    SoundItem currentSoundItem = e.ClickedItem as SoundItem;\r\n    if (this.IsTextToSpeech)\r\n    {\r\n        this.ReadTextToSpeech(currentSoundItem);\r\n    }\r\n    else\r\n    {\r\n        this.PlaySoundItem(currentSoundItem);\r\n    }\r\n}<\/code><\/pre>\n<p>Our click listener calls two different functions depending on whether or not Text-To-Speech mode is enabled. The first plays audio from a file:<\/p>\n<pre><code class=\"language-csharp\">private async void PlaySoundItem(SoundItem sound)\r\n{\r\n    MediaPlayerElement mediaPlayerElement = new MediaPlayerElement();\r\n    Windows.Storage.StorageFolder folder = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync(\"Assets\");\r\n    Windows.Storage.StorageFile file = await folder.GetFileAsync(sound.AudioFilename);\r\n    mediaPlayerElement.Source = MediaSource.CreateFromStorageFile(file);\r\n    mediaPlayerElement.MediaPlayer.Play();\r\n\r\n}<\/code><\/pre>\n<p>While the second uses the <code>SpeechSynthesizer<\/code> API to play some text-to-speech audio:<\/p>\n<pre><code class=\"language-csharp\">private async void ReadTextToSpeech(SoundItem sound)\r\n{\r\n    MediaPlayerElement mediaPlayerElement = new MediaPlayerElement();\r\n    var synth = new Windows.Media.SpeechSynthesis.SpeechSynthesizer();\r\n    synth.Options.SpeakingRate = .7;\r\n    Windows.Media.SpeechSynthesis.SpeechSynthesisStream stream = await synth.SynthesizeTextToStreamAsync(sound.TextToSpeech);\r\n    mediaPlayerElement.Source = MediaSource.CreateFromStream(stream, stream.ContentType);\r\n    mediaPlayerElement.MediaPlayer.Play();\r\n}<\/code><\/pre>\n<p>Sweet! That&#8217;s the core functionality of our soundboard. You can check out the rest of the code that makes it all come together on the <a href=\"https:\/\/aka.ms\/win-dev\/student\/osu\/uwp\/sample\">github repository<\/a>.<\/p>\n<p>Check out the documentation for MediaPlayerElement <a href=\"https:\/\/docs.microsoft.com\/en-us\/uwp\/api\/windows.ui.xaml.controls.mediaplayerelement?view=winrt-22000\">here<\/a> and the documentation for SpeechSynthesizer <a href=\"https:\/\/docs.microsoft.com\/en-us\/uwp\/api\/Windows.Media.SpeechSynthesis.SpeechSynthesizer?view=winrt-22000\">here<\/a> if you want to play with these APIs a bit more.<\/p>\n<h2>Next Steps<\/h2>\n<p>Get out there and start building your own Windows apps!<\/p>\n<p>Here are some links to check out with resources on building for UWP:<\/p>\n<ul>\n<li><a href=\"https:\/\/docs.microsoft.com\/en-us\/windows\/uwp\/get-started\/\">Official UWP Getting Started Documentation<\/a><\/li>\n<li><a href=\"https:\/\/aka.ms\/win-dev\/student\/osu\/uwp\/sample\/getting-started-uwp\">Getting Started with UWP From Scratch<\/a><\/li>\n<li><a href=\"https:\/\/channel9.msdn.com\/Series\/Windows-10-development-for-absolute-beginners\">Windows Development for Absolute Beginners<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/jenius-apps\/ambie\">Ambie Source Code<\/a><\/li>\n<li><a href=\"https:\/\/aka.ms\/win-dev\/student\/samples\">Check out these samples that add more functionalities to your UWP app<\/a><\/li>\n<\/ul>\n<p>Thanks for tuning in! Feel free to reach out on my socials linked above if you have any questions.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This article walks through getting setup with Universal Windows Platform development and showcases how to build a fun Soundboard starter application.<\/p>\n","protected":false},"author":73101,"featured_media":208,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[5,8],"class_list":["post-432","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ifdef-windows","tag-uwp","tag-windows"],"acf":[],"blog_post_summary":"<p>This article walks through getting setup with Universal Windows Platform development and showcases how to build a fun Soundboard starter application.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/ifdef-windows\/wp-json\/wp\/v2\/posts\/432","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/ifdef-windows\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/ifdef-windows\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/ifdef-windows\/wp-json\/wp\/v2\/users\/73101"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/ifdef-windows\/wp-json\/wp\/v2\/comments?post=432"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/ifdef-windows\/wp-json\/wp\/v2\/posts\/432\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/ifdef-windows\/wp-json\/wp\/v2\/media\/208"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/ifdef-windows\/wp-json\/wp\/v2\/media?parent=432"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/ifdef-windows\/wp-json\/wp\/v2\/categories?post=432"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/ifdef-windows\/wp-json\/wp\/v2\/tags?post=432"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}