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.

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

Material Design Themed TimePicker and Clock Controls for WPF

I’ve managed to get the existing WPF controls; DatePicker & Calendar themed as part of Material Design in XAML Toolkit as described in this blog post.

But the fun part was cranking a couple of brand new controls to build the Material Design time picker experience:

  • TimePicker
  • Clock

These are sibling controls to the existing DatePicker and Calendar controls.  I wanted to keep the API experience similar so you can dive straight in without any kind of learning curve.  The Clock can be used in isolation, or use the DatePicker for an easy picker/popup/drop down behaviour.

Here’s a static glimpse at the picker:

Material Design Time Picker

And here’s a gif of the clock in action:

Material Design Clock Demo

There’s nothing complicated about using these, but you will need to get Material Design In XAML Toolkit referenced and set up in your app. Follow the initial tutorial, and head over to GitHub to download the source/examples project.

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

Material Design DatePicker/Calendar Style for WPF

Howdi,

After a bit of toil I have the DatePicker and Calendar WPF control styles done for Material Design in XAML Toolkit. I hope you guys like it!

(Edit: TimePicker & Clock now also available, blogged here)
Material Design templates for DatePicker/Calendar primitive controls.
Material Design templates for DatePicker/Calendar primitive controls.

Please note that the behaviour is not quite identical to that which you might see on Android. These are templates for the existing WPF DatePicker and Calendar primitive controls, and thus, some of the behaviour around month/year selection is driven by the nature of those controls. There is no modal dialog, as I don’t want these templates to get confused with any requirement/API used to manage dialogs in WPF.

I must say that I believe that it is testament to the original design of WPF/XAML – which is now a mature technology – that I could slot these styles in pretty much seamlessly for a control whose code base is around 8 years old. Note that some extra code has gone in to the Material Design Toolkit, bit this is wrapped inside the new templates and thus if you consume these templates you need never concern yourself with it.

Getting started:

If you haven’t taken a look at Material Design in XAML Toolkit yet (or indeed Dragablz) here is a blog post to get started, or download the source from GitHub and fire up the demo projects:

  • MaterialDesignColors.WpfExample
  • MahMaterialDragablzMashUp

Thanks due:

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

Material Design In XAML – Mash Up!

I have previously posted about the Material Design theme for Dragablz.  In this post I will describe how I arrived at this application mock-up, by combining Dragablz, Material Design in XAML Toolkit, and MahApps:

Material Design Demo
Material Design Demo

My initial task when creating that style was to create a separate, and composable way to define the Material Design colour palette for your application.  Making the separation between the colours and the Dragablz Material Design theme immediately paid benefit.  Being a big fan of MahApps and I was easily able to take things a step further and use the palette in conjunction with a MahApps MetroWindow. Encouraging MahApps to pick up my Material Design palette turned out to be easy because of the way the MahApps guys had also separated out their accents.  Very quickly, I had a MahApps MetroWindow up and running, using MahApps themed controls, the Dragablz Material Design theme, and all of which were using the Material Design palette.  It looked pretty good straight away.

I’ve previously posted on how to choose a Material Design palette, but for a refresher, take a look at this App.xaml.

In addition to the Material Design palette, you need to set a base theme; light or dark.  So add this resource dictionary to your App.xaml:

<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" />  

Getting MahApps to use the Material Design palette only takes a few extra lines in your App.xaml.  Firstly, merge in some of the usual MahApps dictionaries:

<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" />

Then, where you specify the primary Material Design colour, setup the MahApps brushes, but instead of pulling in one of the MahApps accent dictionaries, configure them manually, to use the Material Design palette:

<SolidColorBrush x:Key="HighlightBrush" Color="{StaticResource Primary700}" options:Freeze="True" />
<SolidColorBrush x:Key="AccentColorBrush" Color="{StaticResource Primary500}" options:Freeze="True" />
<SolidColorBrush x:Key="AccentColorBrush2" Color="{StaticResource Primary400}" options:Freeze="True" />
<SolidColorBrush x:Key="AccentColorBrush3" Color="{StaticResource Primary300}" options:Freeze="True" />
<SolidColorBrush x:Key="AccentColorBrush4" Color="{StaticResource Primary200}" options:Freeze="True" />
<SolidColorBrush x:Key="WindowTitleColorBrush" Color="{StaticResource Primary700}" options:Freeze="True" />
<SolidColorBrush x:Key="AccentSelectedColorBrush" Color="{StaticResource Primary500Foreground}" options:Freeze="True" />

For a complete example see this App.xaml.

Any controls added to your Window (or Dragablz TabablzControl) will now default to MahApps styles, but use the Material Design palette, leaving your application looking pretty good. Having got to this point myself, I couldn’t help but start playing around a bit further with some Material Design. I created a list box with a few cards and the result looked pretty promising:

MaterialDesignEarlyPrototype

It wasn’t long before I went even further and started styling a whole bunch of controls, and ended up with these:

MaterialDesignDemo2

I’ve packaged all these themes (and will continue to add to) on NuGet:

Install-Package MaterialDesignThemes

Where appropriate in your app you can include one or more of the contained resource dictionaries and use the Material Design style for a control in place of the MahApps. All of your other controls will still use the MahApps themes, meaning your application should always look great. A thorough-bred mash-up 🙂

To select the appropriate resource dictionary and style name the best thing to do is download the source/demo solution from GitHub and run the two projects in the solution:

  • MahMaterialDragablzMashUp
  • MaterialDesignColors.WpfExample

Or, take a look at this MainWindow.cs.

Hope that all helps you get a good looking application up and running quickly!

As an end note I must mention this great piece of styling in WinForms, which inspired me to create the Material Design theme for Dragablz in the first place.

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

How to use the Material Design theme with Dragablz Tab Control

In this post I will demonstrate how to – very quickly – combine Dragablz and MaterialDesignColors in WPF to create a great looking control which supports full tear out and can use the Google Material Design colour palette.

Dragablz Tab Contrtol and Material Design
Dragablz Tab Contrtol and Material Design

Start a new WPF project.  We rely on two NuGet packages, so get them installed straight away.  Install from the Package Manager tool in Visual Studio, or, from the NuGet console run these commands:

Install-Package Dragablz
Install-Package MaterialDesignColors

In the MainWindow.xaml, setup a simple usage of Dragablz TabablzControl:

<Window x:Class="MaterialDesignTabExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:dragablz="clr-namespace:Dragablz;assembly=Dragablz"
        Title="Material Design Demo" Height="350" Width="525">
    <dragablz:TabablzControl>
        <dragablz:TabablzControl.InterTabController>
            <dragablz:InterTabController />
        </dragablz:TabablzControl.InterTabController>
        <TabItem Header="HELLO">
            <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">Hello World</TextBlock>
        </TabItem>
        <TabItem Header="MATERIAL">
            <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">Material Design</TextBlock>
        </TabItem>
        <TabItem Header="DESIGN">
            <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">Looks Quite Nice</TextBlock>
        </TabItem>
    </dragablz:TabablzControl>
</Window>

Already if you run this project you will have a tab control that supports Chrome-style tearing out of tabs. But it wont look too good. So, the next step is to bring in the Material Design colours, and tell Dragablz to use the Material Design style.

Open up your App.xaml. We have to merge in three dictionaries.  The first two are to set up your Material Design colour palette.  The MaterialDesignColors assembly contains a ResourceDictionary for each color (a collection of hues and accents).  To create a full palette we need to bring in a primary colour, set up some hue brushes, and then bring in a secondary color for our accent color.  The third resource dictionary is to include the Dragablz theme for Material Design.  Finally we instruct our tab control to use the correct style.

Don’t worry, it’s not too complicated.  The full App.xaml is below:

<Application x:Class="MaterialDesignColors.WpfExample.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:dragablz="clr-namespace:Dragablz;assembly=Dragablz"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <!-- primary color -->
                <ResourceDictionary>
                    <!-- include your primary palette -->
                    <ResourceDictionary.MergedDictionaries>
                        <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/MaterialDesignColor.Indigo.xaml" />
                    </ResourceDictionary.MergedDictionaries>
                    <!--
                            include three hues from the primary palette (and the associated forecolours).
                            Do not rename, keep in sequence; light to dark.
                        -->
                    <SolidColorBrush x:Key="PrimaryHueLightBrush" Color="{StaticResource Primary100}"/>
                    <SolidColorBrush x:Key="PrimaryHueLightForegroundBrush" Color="{StaticResource Primary100Foreground}"/>
                    <SolidColorBrush x:Key="PrimaryHueMidBrush" Color="{StaticResource Primary500}"/>
                    <SolidColorBrush x:Key="PrimaryHueMidForegroundBrush" Color="{StaticResource Primary500Foreground}"/>
                    <SolidColorBrush x:Key="PrimaryHueDarkBrush" Color="{StaticResource Primary700}"/>
                    <SolidColorBrush x:Key="PrimaryHueDarkForegroundBrush" Color="{StaticResource Primary700Foreground}"/>
                </ResourceDictionary>

                <!-- secondary colour -->
                <ResourceDictionary>
                    <!-- include your secondary pallette -->
                    <ResourceDictionary.MergedDictionaries>
                        <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/MaterialDesignColor.Yellow.xaml" />
                    </ResourceDictionary.MergedDictionaries>

                    <!-- include a single secondary accent color (and the associated forecolour) -->
                    <SolidColorBrush x:Key="SecondaryAccentBrush" Color="{StaticResource Accent200}"/>
                    <SolidColorBrush x:Key="SecondaryAccentForegroundBrush" Color="{StaticResource Accent200Foreground}"/>
                </ResourceDictionary>

                <!-- Include the Dragablz Material Design style -->
                <ResourceDictionary Source="pack://application:,,,/Dragablz;component/Themes/materialdesign.xaml"/>                

            </ResourceDictionary.MergedDictionaries>

            <!-- tell Dragablz tab control to use the Material Design theme -->
            <Style TargetType="{x:Type dragablz:TabablzControl}" BasedOn="{StaticResource MaterialDesignTabablzControlStyle}" />
        </ResourceDictionary>
    </Application.Resources>
</Application>

And that’s it. Fire up your baby and you are done. You can change the colours by changing the two colour resource dictionaries which are referenced. You can also tweak the hues, but do not change the brush names.  Dragablz will be looking for these.

Links:

Enjoy!