.Net, C#, MahApps, Material Design, UI, Uncategorized, UX, WPF, xaml

Happy 2nd Birthday to Material Design In XAML

Happy 2nd Birthday!

Material Design In XAML Toolkit Turns Two Years Old

On 1st February 2017 Material Design In XAML marks it’s 2nd year since it appeared on GitHub. Right up front I have to apologise for all the bugs I haven’t fixed. Plenty of people are helping out, but the project can only move so fast. I always try to prioritise API quality over cramming in more fixes and updates. Hopefully this shows, as I feel that on the whole the library is easy to use, robust, and ultimately helps make apps look great.

birthdaycake

It’s been a busy, successful, and rewarding two years. Sometimes frustrating, always educational. I’m continually dealing with users over email, Twitter, GitHub, Gitter; it’s now got to the point where support is probably 75% of the time I spend on the project. Surely the biggest highlight for me was getting a Microsoft MVP award off the back of this work (and Dragablz), and traveling to Seattle for the MVP Summit. It was great to meet so many people I’ve got to know on GitHub and Twitter.

Two years in I’d like to share some stats on this project. .Net itself is undergoing major open source shakeup, with a big emphasis on the web/ASP side of things. WPF is perhaps more of a “niche” tech, and may not be the bleeding edge XAML platform a anymore, but still has plenty of use, and the some of these stats illustrate the continuing popularity of WPF and the growing popularity of the toolkit:

  • Nuget downloads: 84,839
  • Average Nuget downloads per day: 118
  • GitHub stars: 2,340
  • GitHub forks: 4734
  • GitHub average views per day: 1675
  • GitHub average unique visitors per day: 319
  • Website average unique visitors per day: 177
  • Gitter chat room users: 300+ users

Two years ago, all these stats were a big fat zero. The trend has been upward ever since. I’ve seen and supported students, enterprises and hobbyists use the toolkit to help bring modern styling, palettes and UX flow to their desktop apps, and there are now
continually new projects appearing on GitHub referencing the library.

This isn’t a monster JavaScript framework, and is much smaller than friend, and big-brother WPF project, MahApps. But it’s healthy, and it’s growing.

Currently I’m focusing on “doobry”, a NoSQL editor for Azure DocumentDb. I feel this is becoming a great example of how to utilise Material Design In XAML on the desktop to create useful, attractive apps. Obviously there will be more to come for the toolkit itself over the next 12 months.

doobry

Thanks to all the users, contributors and everyone who has supported the library over the last 2 years!

(Birthday Cake from https://material.uplabs.com/posts/happy-birthday-icon

Advertisement
Design, UI, UX

UX Crimes Against Browser Notifications

Notifications are an issue.  We are overloaded with them.  A long time ago computers were invented to do things for us.  But now one of their primary purposes seems to be to sell us stuff or to get us to visit web pages or apps for longer (and of course that just leads to more advertising or selling).

My phone now  bombards me with so many notifications I have reached saturation point.  I just don’t care any more and I’m suppressing all notifications for an apps at OS level without a second thought.

It seems the latest onslaught seems to be the “no permanent opt out” UX anti-pattern which is starting to appear on websites, now that browsers are implementing notification APIs.

Just check this:

linkedin-nooptout

I can’t say “No”.  Just “Later”.  The website doesn’t trust me to answer the way it wants, so it will enforce the question on me, at regular intervals, for perpetuity.  I can hear the excuses from those responsible, “but the user might change their mind, how will they find the setting?”

Well, I’ve yet to change my mind.

Here’s another example of this nefarious anti pattern in action:

C1J4h7uXUAAnUbp.jpg

I’ve lost track of the amount of times I’ve now had to answer this question from Twitter.

It has become beyond irritating.

 

C#, Design, MahApps, Material Design, UI, UX, WPF, xaml

Icon Pack – Material Design In XAML 1.4

New for release 1.4 of Material Design In XAML Toolkit is a full icon pack.  Icon design is a skill itself and finding or creating good icons when designing an application can be a time consuming task.   To help  in this regard I am pleased to announce that the entire Material Design Icons collection is now included in the library.

MaterialDesignIcons.png

It’s a  great collection, containing over 1,400 icons, including many of  the standard icons we see on Android phones and many more additional icons added by its own community.   It’s worthwhile heading over to the website to get an overview of the icons, and there’s a search feature to help  you track down the icon you’re after.

Using the icons in your WPF application is easy.  Assuming you’ve already installed Material Design In XAML Toolkit, the XAML is as simple as:


<materialDesign:PackIcon Kind="ShareVariant" />

To give you: share-variant-16.png

The icons are SVG based, so scale nicely:

<materialDesign:PackIcon Kind="ThumbUp" Height="24" Width="24" />
<materialDesign:PackIcon Kind="ThumbUp" Height="36" Width="36" />
<materialDesign:PackIcon Kind="ThumbUp" Height="48" Width="48" />

thumb-up-24.png  thumb-up-36.png  thumb-up-48.png

You can see the entire icon collection in the main demo application:

IconPack.png

MahApps

Furthermore, the base class for the icon has been added to ControlzEx (credit to @punker76 for this idea), so in the future you may well see MahApps use the same API for Modern Design Language icons, giving WPF developers a common, simple icon XAML syntax:

<materialDesign:PackIcon Kind="SomeMaterialIcon" />
<mahApps:PackIcon Kind="SomeModernIcon" />

Release Details

Various other fixes, enhancements, performance improvements have recently gone into the library.  Versions 1.3.1, 1.3.2, and now 1.4.0 contain some welcome community contributions.  To see details of all changes hit the Releases GitHub page.

.Net, C#, Design, Material Design, UI, UX, WPF, xaml

WPF Dialog Boxes In Material Design In XAML Toolkit

(Note this article refers to a pre-release version, which can be found on nuget provided pre-release versions are included in your search.)

Message boxes.  Ever a source of frustration in WPF.  MahApps has some nice dialog boxes to which I recently helped out with an MVVM API, but Material Design In XAML Toolkit can run with or without MahApps so I wanted a custom implementation which would meet these goals:

  • Look similar to the dialogs we see on Android phones
  • Have an API which is useable from XAML, code-behind, and MVVM
  • Provide full flexibility on the content of the dialog.

All software is evolution and after a reasonable attempt of doing something similar for a client – which ended up with a bit of a code-smell around callbacks from the API – I’ve come up some composable pieces which I hope are flexible, easy to use, and – most importantly – provide an attractive GUI 🙂

The cornerstone is the DialogHost control.  It’s a content control, meaning the underlying content over which the popup dialog will be displayed can be targeted; to a specific area of your app, or the entire Window content.


<md:DialogHost>
    <md:DialogHost.DialogContent>
        <dialogContent />
    </md:DialogHost.DialogContent>
    <mainContent />
</md:DialogHost>

When the dialog is open, the underlying content will be dimmed and disabled.

Material Design Dialog

DialogHost.DialogContent (associated with DialogHost.DialogContentTemplate) is your typical XAML content object property for setting the content of your dialog.  You can infer from this that you can use MVVM to bind content, but there are multiple ways of populating the content, showing the dialog, closing the dialog, and processing responses, so here’s a list of all the strategies for using the dialog (after the gif):

Material Design Dialog

Open Dialog Strategies

DialogHost.OpenDialogCommand

<Button Command="{x:Static md:DialogHost.OpenDialogCommand}" />

RoutedCommand typically used from a button where optional content can be provided via the CommandParameter.

DialogHost.IsOpen

<md:DialogHost IsOpen="True" />

Dependency property, to be triggered from XAML, set from code-behind or via a binding.  Content must be set in DialogHost.DialogContent.

DialogHost.Show

DialogHost.Show(viewOrModel);

Async/await based static API which can be used purely in code (for example from in a view model).  Content can be passed directly to the dialog.

Close Dialog Strategies

DialogHost.CloseDialogCommand

<Button Command="{x:Static md:DialogHost.CloseDialogCommand}" />

RoutedCommand, typically used on buttons inside the dialog, where the command parameter will be passed along to the dialog response.

DialogHost.IsOpen

<md:DialogHost IsOpen="False" />

Dependency property, to be triggered from XAML, set from code-behind or via a binding.

HANDLE CLOSE STRATEGIES

The DialogClosingEventHandler delegate is key.  It provides the parameter provided to DialogHost.CloseDialogCommand, and allows the pending close to be cancelled.

The following mechanisms allow handling of this event, via code-behind, MVVM practices, or just from the code API:

DialogHost.DialogClosing

<md:DialogHost DialogClosing="DialogHost_OnDialogClosing" />

Bubbling RoutedEvent, which could be used in code-behind.

DialogHost.DialogClosingAttached

<Button Command="{x:Static wpf:DialogHost.OpenDialogCommand}" md:DialogHost.DialogClosingAttached="DialogHost_OnDialogClosing" />

Attached property, which accepts a DialogClosingEventHandler which makes it easy to subscribe to the closing event in a more localized area of XAML.

DialogClosing.DialogClosingCallback

<md:DialogHost DialogClosingCallback="{Binding DialogClosingHandler}" />

Standard dependency property which enables the a DialogClosingEventHandler implementation to be bound in, typically from a view model.

DialogHost.Show

var result = await DialogHost.Show(viewOrModel, ClosingEventHandler);

The async response from this method returns the parameter provided when DialogHost.CloseDialogCommand was executed.  As part of the Show() signature a DialogClosingEventHandler delegate can be provided to intercept the on-closing event, just prior to the close.

More Examples

More complete usage examples can be found in MainDemo.Wpf which is part of the Toolkit solution, primarily in MainDemo.Wpf/Dialogs.xaml.

.Net, C#, Design, Material Design, UI, UX, WPF, xaml

Bending the WPF ProgressBar

There’s plenty progress loop controls around for WPF, but for Material Design In XAML Toolkit I really wanted to stick to “themeing” existing framework controls where-ever possible. Here’s examples of what were trying to achieve from Google’s own documentation, if you have an Android phone you’ll no doubt have seen these in action:

Before I tackled the style I spent a few weeks bouncing ideas around in my head.  To create the circular effect we’d have to dust off the trigonometry but I really wasn’t sure if I cold pull it all off inside a WPF Style, without creating a new control, or at least inheriting (yuck) from ProgressBar.  ProgressBar says it all.  It wasn’t really designed to go where I wanted it to go and whilst weighing things up I reflected into the ProgressBar.cs source:


//----------------------------------------------------------------------------
// File: ProgressBar.cs
//
// Description:
// Implementation of ProgressBar control.
//
// History:
// 06/28/2004 - t-sergin - Created
//
// Copyright (C) 2004 by Microsoft Corporation. All rights reserved.
//
//---------------------------------------------------------------------------

Okaaaayyy…so using the ever flexible WPF we are still taking something from 2004 and trying to theme it using 2015 design trends.  Should be fun!  There are a few TemplatePart’s which the code it expects – to draw a standard bar – but fortunately the control is also gracious enough to operate without them.

To create the looping progress ring thingy a simple arc path should do the job:

<Path>
  <Path.Data>
    <PathGeometry>
      <PathFigure StartPoint="?">
        <ArcSegment Size="?" IsLargeArc="?" Point="?" SweepDirection="Clockwise" />
      </PathFigure>
    </PathGeometry>
  </Path.Data>
</Path> 

But you’ll see from the attributes with a ? we’ve got 4 values we’ve got to complete:

  • PathFigure.StartPoint: pretty simple, start the arc at the top, on the middle of the X axis
  • ArcSegment.Size: easy again, this is the radius, so half the size of the control
  • ArcSegment.IsLargeArc: to draw anything over 180deg, this needs to be set to true. We’ll need a multiple values to figure out if we are over half way through progress: ProgressBar.Minumum, .Maximum, .Value
  • ArcSegment.Point: This is where from the StartPoint we need to draw our arc around to. Again we’ll need ProgressBar.Minumum, .Maximum, .Value, and with the wonders of trigonometry we can figure this out.

No worries though, we can wrap all of these little calculations in a bunch of IValueConverter and IMultiValueConverter implementations.  In reality then, bending a straight progress bar into a circle is pretty simple.  The PathFigure – now, peppered with a bunch of value converters – looks a bit like this:


<PathFigure StartPoint="{Binding ElementName=PathGrid, Path=ActualWidth, Converter={StaticResource StartPointConverter}, Mode=OneWay}">
<ArcSegment Size="{Binding ElementName=PathGrid, Path=ActualWidth, Converter={StaticResource ArcSizeConverter}, Mode=OneWay}" SweepDirection="Clockwise">
<ArcSegment.IsLargeArc>
<MultiBinding Converter="{StaticResource LargeArcConverter}">
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Value" />
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Minimum" />
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Maximum" />
<Binding ElementName="FullyIndeterminateGridScaleTransform" Path="ScaleX" />
</MultiBinding>
</ArcSegment.IsLargeArc>
<ArcSegment.Point>
<MultiBinding Converter="{StaticResource ArcEndPointConverter}">
<Binding ElementName="PathGrid" Path="ActualWidth" />
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Value" />
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Minimum" />
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Maximum" />
<Binding ElementName="FullyIndeterminateGridScaleTransform" Path="ScaleX" />
</MultiBinding>
</ArcSegment.Point>
</ArcSegment>
</PathFigure>

(I don’t think WordPress wants to format that…)

We’re not done there though.  Material Design has extra animation flourishes to provide the extra pzazz.  If you look at the determinate loop in the video above, you’ll see that the whole ring is rotating in addition to drawing out the arc representing completion.  Something, a bit like this:

ProgressRingDoubleRotate

By applying a RotateTransform to the Path itself, and using yet another converter to calculate the rotation according to the percent of completion we can pretty close to the Google effect.


<Path.RenderTransform>
<TransformGroup>
<RotateTransform x:Name="RotateTransform" CenterX="{Binding ElementName=PathGrid, Path=ActualWidth, Converter={StaticResource RotateTransformCentreConverter}, Mode=OneWay}" CenterY="{Binding ElementName=PathGrid, Path=ActualWidth, Converter={StaticResource RotateTransformCentreConverter}, Mode=OneWay}">
<RotateTransform.Angle>
<MultiBinding Converter="{StaticResource RotateTransformConverter}">
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Value" />
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Minimum" />
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Maximum" />
</MultiBinding>
</RotateTransform.Angle>
</RotateTransform>
</TransformGroup>
</Path.RenderTransform>

I’ve actually built further animation storyboards on top of this to try and get close to the indeterminate effect.  It’s not quite perfect yet, but close enough for what I released in version 1.0 of Material Design In XAML Toolkit.  Here’s a gif of how things were looking in that release:

Progress Loops

And, in keeping with my original challenge of staying close to the original .Net Framework controls, usage is pretty straight forward:


<ProgressBar Style="{StaticResource MaterialDesignCicularProgressBar}" Value="50" />

To see it in action run up the demo project which is part of the main source.

The actual final style can be found here:

https://github.com/ButchersBoy/MaterialDesignInXamlToolkit/blob/master/MaterialDesignThemes.Wpf/Themes/MaterialDesignTheme.ProgressBar.xaml

And – as there are a whole bunch of converters – they warrant their own namespace here:

https://github.com/ButchersBoy/MaterialDesignInXamlToolkit/tree/master/MaterialDesignThemes.Wpf/Converters/CircularProgressBar

.Net, C#, Design, Material Design, UI, UX, WPF, xaml

Version 1.0 of Material Design In XAML has arrived!

Well, this project kinda came out of nowhere, but has proven to be pretty popular and I’ve really enjoyed getting it to this state: version 1.0!   It’s officially a non-alpha, non-beta, totally live thing!!

I’ve cranked up my contributions over the last month to push it over the line for its for first official release, recently adding runtime palette switching via the PaletteHelper/Swatch API, a new ColorZone control to help you design your layouts, and more granular control of ripples and shadows.  A few styles and animations have also been tweaked to really improve the look and feel.

To go with version one I’ve completely re-worked the demo app, as illustrated in the video.  It’s really worth checking, it might just give you some inspiration for your WPF apps!

And if you haven’t seen I recently launched a new home page for the project: materialdesigninxaml.net, which includes a Get Started section.

There’s still plenty more to come for both Material Design In XAML and Dragablz but I will be treating myself to a little break for a week or two!

Material Design, react.js, UI, UX

React.js and Material Design Lite

I’m a bit of a React.js fan lately, and with the arrival of Google’s Material Design Lite, I decided to combine them for a little project I’m throwing together.  Turns out to be pretty easy.  To simplify the Getting Started, you need to include a .css and .js file in your page:

<link rel="stylesheet" href="https://storage.googleapis.com/code.getmdl.io/1.0.0/material.grey-blue.min.css" />
<script src="https://storage.googleapis.com/code.getmdl.io/1.0.0/material.min.js"></script>

…and then show a Material Design button using the following class names:

<button class="mdl-button mdl-js-button mdl-button--raised mdl-button--accent mdl-js-ripple-effect">
  Button
</button>

The small gotcha for using templating techniques for dynamic pages such as with React.js is that for buttons, and other items, dynamically added you need to call a bit of script to upgrade the button:

//where button is your DOM element
componentHandler.upgradeElement(button, 'MaterialButton');

But when we come to create our React class, that’s easily handled in componentDidMount, leaving my Material Design Lite button class looking like this:

var MdlButton = React.createClass({
	handleClick: function() {
		this.props.onClick();	
	},
	render: function() {
		return (
			<button ref="btn" className="mdl-button mdl-js-button mdl-button--raised mdl-button--accent mdl-js-ripple-effect"
					onClick={this.handleClick}>
				{this.props.content}
			</button>
		);
	},
	componentDidMount: function() {
		componentHandler.upgradeElement(React.findDOMNode(this.refs.btn), 'MaterialButton');		
	} 
});

One small thing to note is the second arg to upgradeElement where we are passing in ‘MaterialButton’. As of now the docs aren’t overly clear on this, but it’s the name of the Javascript function object defined in the source. So, if we want to create a check box React class we can dig in to the Material Design Light source code in GitHub, and confirm that we’d pass ‘MaterialCheckbox’ into upgradeElement.

No doubt the community will provide a full library for this in time, but it doesn’t take much to combine these two libraries.

.Net, C#, MahApps, UI, WPF, xaml

Using MahApps Dialog Boxes in a MVVM Setup

Finally, after a couple of years of take, take, take; I’ve made a contribution to MahApps.  Working in a financial institution it’s not always easy to commit back to open source projects, so with a little bit of out-of-hours work I’ve solved a little problem I’ve seen a few people asking: “how do you use MahApps dialog boxes in an MVVM setup?”  And now my conscience is clear. 😉

Now You Can Launch a Dialog Box From a View Model.

There’s a couple of simple things you have to do:

1) Use an attached property in your Window to register your view model with the dialog sub-system.

Assuming your View’s DataContext is set to the view model from where you want to launch the dialog, add these attributes:


<Controls:MetroWindow 

        xmlns:Dialog="clr-namespace:MahApps.Metro.Controls.Dialogs;assembly=MahApps.Metro" 
        Dialog:DialogParticipation.Register="{Binding}"
 >

2) Grab & Use DialogCoordinator to open dialogs.

You can instantiate DialogCoordinator directly, or, good citizens will probably want to inject in the interface IDialogCoordinator into their view model.  This will play nicely with TDD, and is agnostic to whatever DI framework you may be using.

Without a DI framework you could just do something like this:


new MainWindowViewModel(DialogCoordinator.Instance);

Opening up a dialog from your view model is now easy, using the IDialogCoordinator instance.  To most methods the first parameter named “context” will typically be your view model.  This is how the coordinator will match the view model to the window (with what was registered in step 1) and display the dialog.  If you have multiple windows open, the dialog will display on the correct window.  Show your dialog from inside your view model just like this:


_dialogCoordinator.ShowMessageAsync(this, "Message from VM", "MVVM based dialogs!")

If you want to see this in action and follow the code through open up the MahApps MetroDemo project (part of the MahApps source code), and launch from the “Dialogs” Menu:

Dialogs via MVVM in MahApps
Dialogs via MVVM in MahApps

This should make it into release 1.2.0.

Design, Material Design, UI, UX

Open Sourcing a Logo

Open source doesn’t have to just apply to code.  I’ve been applying my XAML skills to Material Design In XAML Toolkit to help other developers quickly craft good looking user interfaces in WPF.  I’m pretty happy with the results, and in some of my own projects I’ve produced some striking applications using the toolkit.  Despite doing this, I readily admit I’m no designer.  For such a visually focused code library I really wanted a logo, but knew I could never do the task justice.

So I threw the task out to the community.

I created an issue on GitHub, tweeted a bit, posted on Reddit.  And waited.  Pretty much bang on 2 weeks later a result came back from a young guy called Sam, and I’m really happy with it:

Material Design In XAML Toolkit

Sam or “snalty” can be found on Twitter, and you can see some of his other designs on his blog.

In summary, a great bit of collaboration helping to push Material Design In XAML Toolkit further along.