Skip to main content

Bring your WPF apps to life – Snazzy Animated Window Borders

Checkout my project on GitHub showing how to create animated window borders in WPF. Before I explain, watch the video to see what I mean:

To try it out for yourself, download the demo app.

These kinds of animations have a range of applications:

  • Instant feedback, when button is pressed or action performed
  • Loading animations
  • Progress bars, where animation progress = percentage progress
  • Red flashes for warnings/alerts

The project was born while working on my upcoming HTTP Client desktop app HyperPost. I wanted a loading animation to play when a request was sent.

Remember old web browsers used to have very thin progress bars while a page was being fetched and rendered? Many mobile web browsers still have this ... see the Chrome for Android screenshot below.

But these loading bars are placed between the application toolbar and the webpage content, whereas for my apps, these are not easily distinguishable. So I thought "where can I put a progress bar without breaking up the UI?" ... "how about on the window border itself?". It works surprisingly well.

Now I'll proceed to give a little FAQ summary, and explain the inner-workings.

Follow the instructions on the GitHub Readme. You can clone the project, and build on it. Or setup the required dependencies and copy the code into your own project.

Your Window class should take the following structure where <c:BorderLoop> is the component containing one example border animation effect. Different components are available for different effects, each with different properties such as BColor to set the color of the border animation.

<Window ...>
    <Grid>
        <!-- Add animations you want to use here -->
        <c:BorderLoop x:Name="BorderLoop" BColor="Yellow"></c:BorderLoop>

        <!-- Place your windows contents within this grid -->
        <Grid Margin="1">
            ...
        </Grid>
    </Grid>
</Window>

Then to start the animation use the .Start() method, e.g. BorderLoop.Start();.

Can I use it for border animations on other WPF controls?

Yes. Use the same structure as above in place of your component:

<Grid>
    <c:BorderLoop x:Name="BorderLoop" BColor="Yellow"></c:BorderLoop>
    <MyControl Margin="1"/>
</Grid>

How does it add colours above the TitleBar?

To colour the borders, the window border width is actually set to 0, and custom controls are used within the window to make the colours appear. That means on the top border, a control has to be rendered above the titlebar. So how does that work?

In WPF titlebars are difficult to customise. Default WPF titlebars cannot be changed, hence they need to be removed entirely with a custom title bar put in their place. That's not an easy thing to do; you often loose native functionality by reimplementing titlebars youself. See my previous attempts creating customiable titlebars in WPF, and HTML-based WPF titlebars in blazor dektop apps.

... but WinUI provides much better controls for this. Hence I recommend using the ModernWpf framework which takes native titlebars from WinUI and lets you use them in your WPF application - and place additional controls like fake window borders within them! This project uses ModernWpf for this purpose.

How do the animations work? Are there performance overheads?

It uses WPF's built-in animations and storyboards … so it's very efficient.

However, animations in WPF are usually pixel based. You assign a From value and a To value in terms of pixels. This doesn't work very well for window border animation which need to span the full width or half-width or third-width of the window, and smoothly animate between these points in a way that scales correctly on window resizes. Of course that's never a problem in web development as CSS allow percentage based widths and heights, but sadly not in WPF 😢

Instead the way to achieve this in WPF is using Grids with column/row widths/heights using stars. E.g. setting a column to have width "43*" and a second column of width "100*" creates a 43:100 ratio or width of 43%.

Animating grid column widths and row heights like is this not possible out-of-the-box, instead I found an existing custom AnimationTimeline implementation from MahApps. You can find the source here.

You assign the component a name:

<Grid.ColumnDefinition Width="*" x:Name="MyColumn"/>

If you look at the codebehind for each animation component, you'll see the animations created like this:

GridLengthAnimation anim = new GridLengthAnimation();
anim.From = new GridLength(fromValue, GridUnitType.Star);
anim.To = new GridLength(toValue, GridUnitType.Star);
anim.Duration = ... ;
Storyboard.SetTargetName(anim, "MyColumn");
Storyboard.SetTargetProperty(anim, new PropertyPath(ColumnDefinition.WidthProperty));

The top dash animation is more complex, it consists of 16 columns which alernate between empty and coloured-in. The idea being that you only need to animate the widths of the first and last columns. The animation comes in two stages, first expanding width of column 2 and shrinking column 16, followed by expanding column 1 and shrinking column 15. After which, the animation immediately resets.

The complete border dash animation applies this to all 4 edges of the window at the same time, to make it look like the dashes are flowing around the entire window border.

That’s it

If you find it useful please star the github repository ⭐⭐⭐

Comments

Popular posts from this blog

Terminals in Sublime Text 3

TL;DR - Need a quick answer on how to create terminals in Sublime Text 3? Scroll down and watch the video or read the instructions below it. A while ago I started a series on YouTube of 'Sublime Text Tips'. Sublime Text 3 is one the best code editors currently in existence (fact), but most people just install it an use it without realising how it can be customized and extended to meet your needs. My aim was to release a series of videos explaining some of these widely unknown capabilities. I got as far as the third video and then got distracted with other things 😅 But recently I noticed the 3rd video I made has been increasing in popularity. For at least 6 months it sat at less than 200 views, and over the course of the last 2 months it has shot up to 850 (at the time of writing). Perhaps it's coincidence, or perhaps YouTube's algorithms have changed. Either way, there seem to be people who want this information. The video explains how to set up termin

Generating a MSI Installer for a WPF Application

This post serves as a tutorial for creating a MSI installer for your WPF Applications in Visual Studio. For this we use WiX (recommended by Microsoft). Prerequisites I assume you already have a Visual Studio solution containing a WPF Project. And I assume you have some experience with Visual Studio and XML. You do not need any prior knowledge of WiX. Step 1: Install Wix We are going to need WiX to generate our MSI. If you don't already have Wix installed, go ahead and download it from here . You'll be redirected to the relevant GitHub releases page where you can download the .exe file to install WiX.

Best Packages for Sublime Text 3 (Excluding Themes)

Sublime Text 3 is pretty good out-of-the-box but reaches a whole new level when you install some of the great packages on offer. Below I'll list my favourite packages for Sublime Text. These are all packages which will enhance your productivity across all languages, so no themes or language-specific packages will be listed here.