WPF - James Montemagno https://staging.montemagno.com/tag/wpf/ https://staging.montemagno.com/content/images/2017/08/MonogramIcon_Orange_NoBuffer.png WPF - James Montemagno https://staging.montemagno.com/tag/wpf/ Hugo -- gohugo.io Tue, 13 Oct 2026 22:20:07 GMT 60 Code Generation from XAML in Visual Studio is Mind-blowing Awesome https://staging.montemagno.com/code-generation-from-xaml-in-visual-studio/ 605f72ee20df30003b2b3b83 Sat, 27 Mar 2021 18:57:22 GMT

The more and IDE or code editor can do for you the better I say. Visual Studio has been crushing it with new refactorings, IntelliSense, and IntelliCode, one of my favorite features ever. One thing that I have always been hoping for as a XAML developer is deeper connectivity between the XAML and the View-Model. We have seen increased IntelliSense in this area, but with the release of Visual Studio 2019 v16.9 comes code generation from XAML! That is right, you can now have Visual Studio automatically create your properties, commands, and more!

I will walk through this awesome feature for Xamarin.Forms, WPF, and UWP, but if you just want to see it in action, I made an entire video:

Enabling Code Generation

The first thing to do is to create your ViewModel and implement INotifyPropertyChanged (or inherit from something that does). Then just create a control with a Binding associated with it. For example:

<StackLayout>
    <Label Text="{Binding Text}"/>
</StackLayout>

Once you do this, Visual Studio will put little dots under the Text binding and a lightbulb will show up (if you don't see this simply re-compile). The lightbulb will look to assign your x:DataType in Xamarin.Forms or d:DataContext in WPF/UWP.

Lightbulb in Visual studio to set x:DataType

When I selected this option, it auto added the following code:

xmlns:app1="clr-namespace:App1"
x:DataType="app1:MyViewModel"

What is x:DataType you may be asking? Well, it is a compiled binding, which makes your bindings and apps faster! This is an awesome feature of Xamarin.Forms that you should totally use!

With this code in place, you will now see the dots remain and a new lightbulb show up to create a property called Text for you!

Lightbulb and code preview to generate text

Here, it is recommending adding the property and creating a SetProperty method to invoke PropertyChanged, which is AWESOME!!!! Now, at this point you probably want to refactor the code a little bit and create  BaseViewModel that you put this method in and then in future ViewModels it will not attempt to create the code and just add the property. If you are using Mvvm Helpers, you can use this code as your base:

public class ViewModelBase : BaseViewModel
{
	public bool SetProperty<T>(ref T field, T newValue, [CallerMemberName] string propertyName = null) =>
		SetProperty<T>(ref field, newValue, propertyName, null, null);
}

Now, if you add another control with another binding, you will see nice tight code will be generated for you:

Another property being added with only a get/set

Is your mind blown yet?!?!? Mine is! However, it gets even better!

Generating Commands!

Now, let's say we are going to add a Command to a Button we would naturally want that code to be generated as well, correct? Well, you are in luck because it will!

Command and method being created!

This code is really neat because it not only created the command and the method, but it also brought in the correct namespace to use the Xamarin.Forms Command!

Command Generation on UWP/WPF

If you are over on UWP or WPF you will not see this code generation because the core framework does not have an implementation of ICommand. However, if you are using a framework or library such as Mvvm Helpers then it will be smart enough to figure it out and recommend code for you!

Code for a command being generated with Mvvm Helpers

MIND BLOWN!!!! ARE YOU NOT IMPRESSED!?!?!? Amazing!

Cleaner Code with C# 8 & 9!

One of the things you may have noticed is that the code for Xamarin.Forms and WPF/UWP are different in the screenshots. That is because my WPF sample app is using .NET 5, which uses C# 9 by default. The Xamrin.Forms app is using .NET Standard 2.0, which defaults to C# 7. However, you can easily adjust what version of C# is used in your project by adding the LangVersion into your csproj.

<LangVersion>8.0</LangVersion>

Take a look at my previous blog about upgraded a project to C# 9 in a minute.

Once you upgrade to 8.0 or higher the old code:

private ICommand clickCommand;

public ICommand ClickCommand
{
	get
	{
		if (clickCommand == null)
		{
			clickCommand = new Command(Click);
		}

		return clickCommand;
	}
}

private void Click()
{
}

will be upgraded to this lovely clean tight code:

private ICommand clickCommand;
public ICommand ClickCommand => clickCommand ??= new Command(Click);

private void Click()
{
}

Code Generation for Models

So far we have had Visual Studio generate code in our ViewModel classes on our page, but what about our models that are bound to an ItemsSource in a ListView or CollectionView Well no worries, all you need to do is set your x:DataType on your DataTemplate:

<ListView ItemsSource="{Binding Items}">
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="app1:Item">
            <ViewCell>
                <Label Text="{Binding Text}"/>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Then you will see lightbulbs on any control inside of the DataTemplate!!

Code being generated inside of the data model

Again, this is pretty mind blowing and amazing! I was able to create all of my ViewModels and Models all without leaving the XAML!

Just the start!

This is all from me just playing around with Visual Studio 2019 v16.9 for a few minutes exploring this awesome new feature. There is for sure much more to come as Marco from the XAML Tooling team tweeted about the new feature and discussed with commentors about extending the templates for code that is being generated. Also, as of right now this is just a feature on Visual Studio on Windows, but since Visual Studio for Mac uses pretty much the same engine, we can imagine it will make its way to VSM soon.

This is just one of the many features that was included in Visual Studio 2019 v16.9 so check the release notes and upgrade today!

]]>
Distributing a .NET Core 3 WPF and WinForms App with MSIX https://staging.montemagno.com/distributing-a-net-core-3-wpf-and-winforms-app-with-msix/ 5c96b087b2f3d500bff4c987 Mon, 08 Apr 2019 17:55:00 GMT

I could not be more excited for .NET Core 3 that will soon power all of your WPF and WinForms apps in addition to ASP.NET Core and .NET Core apps themselves! You may be saying... James... WPF... WinForms... why even bother? Well, because you may have to support some older apps and with the power of .NET Core 3 as the runtime instead of the .NET Framework it means that we no longer have to worry about what version of .NET is installed on the users machine. It means we can deploy a WPF/WinForms app just by running a .exe on any machine, as the runtime is built right in. Checkout all the details here.

I recently had an idea for a new application for my Twitch stream that I could use when I needed to display a countdown timer. I decided that I should give WPF on .NET Core 3 a try and within a few hours, My Stream Timer was born! Watch the streams here and here,

demo

After I finished up most of the app the tough question started to sink in... how do I distribute and do automatic updates to the app. I know that Squirrel is a super popular way of doing it, but I wasn't sure if it supported .NET Core 3. So I tweeted the question out and within a few minutes was sent towards MSIX.

MSIX

What is MSIX? It is a new app packaging format for Windows applications that supports Win32, WPF, and WinForm apps! Better yet, it provides built in download page, certificate support, and most importantly... automatic updates!!! I was blown away when I read this and was determined to figure it out. Throughout the process I learned a lot about MSIX, .NET Core 3, WPF, and distribution. I have to say I AM A FAN! Before we package up an app, let's talk about the pros and cons of MSIX from my understanding:

MSIX Pros

  • Works with any Win32, WPF, or WinForms apps (regardless if it is .NET Core 3)
  • Enables seemless distribution to the Microsoft store
  • Enable Side-Loading with Easy Download & Install Page
  • Automatic App Updates
  • Easily integrates with Continuous Integration
  • Lights up some Windows 10 features like URI launching

MSIX Cons

  • Only supports Windows 10 for "seemless install mode"
  • Requires special tools on Windows 7/8 (MSIX Installer)
  • Requires side-loaded app to be signed with cert (pretty standard, but not ideal for indie dev).
  • Sandboxes app like a UWP app

With this in mind, let's package up our WPF .NET Core 3 app with MSIX!

Install UWP!

That is right! We will need to install UWP as it contains all of the templates for MSIX packaging:

UWP-INSTALL

Windows Application Packaging Project

With UWP installed we can now add in the packaging project. Simply search for package and it will pop up:

AddNew

When it is time to select the UWP platform I would recommend setting the minimum to 1803 and target to 1809.

Select

From what I can tell you can go farther back, but it is a bit more work

Add App Reference

Just like adding a normal reference to a library the package project can take a reference to another app project. This is how it knows what to bundle up:

package

Configure Platforms and Runtime Configurations

Inside of the WPF project there is a bit of work to do to configure it for x86 and x64. This is accomplished with the RuntimeIdentifiers attribute inside of the .csproj. In addition, we will want to setup a few platforms:

  <PropertyGroup>
    <!--Regular Settings-->
    <Platforms>AnyCPU;x64;x86</Platforms>
    <RuntimeIdentifiers>win-x64;win-x86</RuntimeIdentifiers>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <PlatformTarget>x64</PlatformTarget>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
    <PlatformTarget>x86</PlatformTarget>
  </PropertyGroup>

Setup App Info

Inside of the new packaging project we will find tons of settings and configurations for the new app. This includes a title, description, icons, capabilities, and a bunch more.

Some additional things that we can setup here are declarations such as a Protocol to support URI routing to the app. Here I will set it up so mystreamtimer: opens the app.

Declarations

Distribute!

With just a few steps we are ready to distribute this app. We have a decision to make though. We can go directly to the Microsoft Store(or Business store), which only supports Windows 10, but handles all of our updates, certs, and store listing page for us. Or, we can distribute it ourselves and leverage an Azure App Service to host the app and automatically ship updates... Let's investigate and setup both! On the package project we can right click and go to Store, which gives us options on how to ship it.

Decide

Microsoft Store

This is actually the easiest part and since I have actually shipped UWP apps in the past the process was nearly identical. The first thing we will want to do is Associate App with the Store. This is a quick process once you have your Windows Dev account open. Then we can Create App Packages and say we want to create a new package for the app we just associated with from the store:

StoreAPp

From here we just need to select our architectures (x86 and x64) and click on Create.

This will re-compile the app, package it up, and give us the app we need to upload to the Microsoft Store. It will also give us a test app and power shell script that we can run to test it locally.

Web Distribution & Sideloading

Now, on to the fun part of shipping our app with MSIX and bypassing the app store all together. This is cool because you can enable automatic updates, there is no review process, and it works! At the end of it you even get a cool website that gives you an install page such as this:

Install-page

Create Sideloading Packages

Instead of creating a package for the store we wil create one for sideloading. One nice feature is the checkbox to enable automatic updates!

SideLoad

Just like the Microsoft Store version we will select x86 and x64 architectures for distribution. If you checked the box for automatic updates there is just a tiny bit more to setup such as where your hosting website or file share lives. AKA where are your storing your files for distribution. Then how often you want to check for updates.

Updates

Setup Backend

At this point you may not have your backend setup, so you will probably want to head over to Azure and setup a simple and cheap web app. It is crazy simple and only takes a few minutes to do so. They have great docs on how to configure everything on Azure. The most important part is setting the MIME types in your Web.config.

Upload Files

With the backend hosting site setup and the app package created we can upload all of the files to the server. This includes:

  • index.html
  • The full output folder for the build
  • appinstaller file

I just used FTP to drag and drop in these files, but you could easily automate this process.

Install the App

Now, we have an awesome website with a big Get the app button that will download the app, install it, and check for updates!

You can test out my test server at https://mystreamtimer.azurewebsites.net/. Since I signed it with my test cert you will need to install it. If you are an enterprise or want to do this for real, you will need to buy a cert from someone like Digicert.

Gotchas

Here are a few things that got me when packaging with MSIX since the app is sandboxed.

  1. Saving files to LocalApplicationData actually saved it in a private location that the user couldn't easily get to. I used CommonApplicationData instead.
  2. Hard to test protocal URLs in WPF... have to parse generic StartupEventArgs.
  3. WPF apps can still run multiple instances, so we need to add a Mutex to stop that.
  4. Still need to sign the app with a cert for side-load deployment

Package Up Those Apps

All in all I was really happy with how this project turned out. You can browse the full source code on GitHub and download it from the Microsoft Store today!

]]>
Introducing My Stream Timer: A Countdown Timer for OBS https://staging.montemagno.com/introducing-my-stream-timer-a-countdown-timer-for-obs/ 5ca1b6eab2f3d500bff4c99d Thu, 04 Apr 2019 20:55:00 GMT

I have been streaming on Twitch for over 6 months now. I stream both code on my personal Twitch channel and I also stream games and recordings of Nintendo Dispatch with my buddy Michael over on the official Dispatch Twitch channel. One thing that always bothered me was having to manually mess around with apps to get a simple countdown timer. They were too complex, had too many options, and had a bunch of quirks. So, I decided to build my own, which is out today on Windows 10 called My Stream Timer.

PrettyStreamTimer

My Stream Timer is an elegant and simple to use timer that can be used to count up, down, or do giveaways. It also:

  • Integrates into OBS/SLOBS by writing to disk
  • Intuitive user interface
  • Ability to add more time
  • Can be automated to use with Stream Deck

Countdown Simplified

I wanted to make this app really easy to use. There are only a few tabs that do only one thing. Count up or down. You can set just a few properties:

  • How you want the output to display
  • What you want it to say when it is finished
  • Auto start when you open app
  • File name to output
  • Start, Add Minute, or Reset

When you start a timer the app will start to update and output the results to disk so you can integrate it into OBS/SLOBS:

demo--2-

Optimized for Stream Deck

You can integrate a Open command under System to launch My Stream Timer and start a countdown from a specific amount of time. You don't need to browse for a file location at all as you can input a protocol url:

Format: mystreamtimer://countdown/?mins=6

With this simple command it will launch My Stream Timer and start a countdown from 6 minutes!

In Action

Get It Today

My Stream Timer is available today for free from the Microsoft Store. It is also completely open source on GitHub.

]]>