Jerry Nixon @Work: WPF

Jerry Nixon on Windows

Showing posts with label WPF. Show all posts
Showing posts with label WPF. Show all posts

Tuesday, November 18, 2014

Hey! The future of WPF?

How about a quick chat with the Windows Presentation Foundation team? Not sure what that road map article really meant. We’ll get to the bottom of it. Spoiler alert, it’s awesome and you’ll walk away smiling.

Wednesday, April 30, 2014

Announcing: Developer’s Guide to Microsoft Prism 5.0 for WPF

imagePrism provides guidance in the form of samples and documentation that help you easily design and build rich, flexible, and easily maintained Windows Presentation Foundation (WPF) desktop applications. Using design patterns that embody important architectural design principles, such as separation of concerns and loose coupling, Prism helps you to design and build applications using loosely coupled components that can evolve independently but that can be easily and seamlessly integrated into the overall application. In short, these applications are "built to last" and "built for change." These types of applications are known as composite applications.

Wednesday, September 12, 2012

Friday, July 2, 2010

Inheritable, compound styles in WPF4 with the BasedOn attribute

Maybe you have a base style you would like to enhance for a single or single set of controls. Using the BasedOn property, your style can inherit the settings of the “base” and expand it or override it where you want. It’s that easy.

According to MSDN, each style only supports one BasedOn value. But that does not mean you cannot have a long lineage of inherited styles. 1 –> 2 –> 3 –> 4 and so on. This really makes it nice when you have a large application.

image

Get the code here.

Shimmer and Shine with WPF4 (and, I suppose, SL)

Shine Wouldn’t it be nice if you had a Button or header or some element that, when your mouse selected it (or moved over it) it would animate a cool looking shine?

Take a look at the image on the right. The top two are just sitting there, while the bottom Button (in this case it’s really just a Border) is animating a shimmer.

The technique simply to animate the offset of a linear gradient that is tilted and applied to the border. It’s crazy easy when you see how I do it.

If there’s a trick, it’s accessing the correct gradient stop. Here’s that syntax:
(BorderBrush).(LinearGradientBrush.GradientStops)[1].(GradientStop.Offset)

The other trick is realizing that the gradient stop collection is zero-based. That might get you, too. And they are sorted based on ordinal XAML position and not Offset reference.

Here’s the code.

Wednesday, June 30, 2010

WPF Linear Gradient Fill and animated Fade

So much is not obvious in WPF. For example, say you have a linear gradient filling a control. Want to transition to another color? Just animate to a new brush. Oh, if only you could.

imageOf course, you can switch brushes with a style trigger. But if you want a slow and sexy transition, you are stuck animating each gradient stop one at a time. That’s right. Yuck.

Anyway, there is no time for judgment. Let’s just hope future feature enhancements enable this. Meanwhile, here’s how you do it with WPF4:

The scenario is a simple buttons list. You want them to track your mouse’s movements and highlight. Then lose their highlight slowly as you move away.

I have wrapped them in a ScrollViewer. And these aren’t really buttons, they are just Border controls. But, it just goes to how you can do the same magic to just about any control.

A shared Style resource is attached to each of the Border controls, and if you look at the code (here) you can see the syntax is tricky, but not rocket science.

Thursday, June 24, 2010

WPF Data Presentation: step-by-step

My scenario is simple. I wanted to do a search for Contacts, and have the results be a bunch of rolodex cards loaded in a WrapPanel. Here’s how I did it.

Please note that each screen shot builds on the previous screen shot. You can’t just jump to one of them and get something (unless you jump to the end).

 

Sample Data

I needed some classes. I don’t like declarative data. I like classes. So I created Contact and Contacts. There’s nothing special about them. Here’s the code:

image

See that ObservableCollection I am using for People? That’s just like List<Person> except ObservableCollection has events indicating membership has changed.

 

Databinding the ItemsControl

Next, data bind People to to the ItemsControl. The ItemsControl reminds me a lot of the Asp.Net Repeater control. Other controls handle layout. And here’s how to do it:

image

See the PersonTemplate I created? I could have made it a resource of the Grid, or a property of ItemsControl. Eventually, I will move it to a separate file. Here’s the code behind:

image

Yep. That’s it – and we won’t be changing this code behind for the rest of the scenario. And here’s what it looks like when you run it:

image 

 

Adding a WrapPanel

This is a start, right? But where are my cards? My WrapPanel? And where is a little formatting to make this look like a professional app and not a sample? First the WrapPanel:

image

See how the WrapPanel ends up as a child of the ItemsControl? I point that out because it is not 100% intuitive to do things like that. But that’s the technique. Here’s the UI:

image 

 

Adding Grouping

Now, in a sense, we are done. But let’s add grouping? We’ll need a CollectionViewSource to do that. It defines which property is the “group by” property. Here’s now:

image

See the CollectionViewSource with a PropertyGroupDescription of Title? Now, it doesn’t have a reference to the People class. Not yet. I will do that from Code Behind like this:

image

See the FindReference bit? That’s where I go get the CollectionViewSource (there’s no other way, really) so I can set its Source property to People.

Now, to show groups we specify a HeaderTemplate under GroupStyle. There will be an item for every group header with a WrapPanel as its next sibling with a filtered list of items. Here:

image

See that I have added a new HeaderTeamplate in the Windows Resources? Like PersonTemplate, we’ll be moving that off to it’s own file.

Here’s a really helpful note: no matter what field you are filtering on, in the HeaderTemplate you bind to Name. You see, the header is binding to the group, not the item anymore.

The real magic around grouping is handled in ItemsControl.GroupStyle. It allows you to indicate the HeaderTemplate if the CollectionViewSource indicates a Group.

Here’s the resulting UI:

image 

 

Adding Sorting

But what if you wanted to add some sorting? I want to sort the Groups Descending (Z-A) and I want to sort the People Ascending (A-Z). Is this difficult? Not with CollectionViewSource.

image

There’s something very important to notice, and I highlighted it in the screenshot. See that I have added a namespace reference to System.ComponentModel – that is important because SortDescription is located there (for some reason). Here’s the result:

image 

 

Moving Resources to Files

Now, let’s clean out those Windows.Resources. This will make your XAML smaller (more manageable) and let you reuse resources on separate Pages or Windows.

First you will need to add a ResourceDictionary to your project (it’s just a file); pick it from the Add New Item dialog. Here’s a screen shot:

image

All I did was Copy-n-Paste from Windows.Resources into my PersonTemplate and HeaderTemplate files. Then I replace them with this in Windows.Resources:

image

In so many ways this is like a CSS link. Now my DataTemplates are stored in separate files that can be checked out by separate developers. By the way, I only left the CollectionViewSource to show you how to combine linked and local resources.

 

Styling the Output

Let’s take some time to make our data look a little nicer. We’ll start with the header. Let’s make it look nice – but remember, not too sexy. Let’s not unleash every WPF feature on our user.

If we update the HeaderTemplate with some extra style like this:

image

We get this:

image

If we update the PersonTemplate with some style like this:

What’s that? You can’t read all the code? Don’t sweat it. 1) you need to learn to develop a little on your own and 2) I will include all the code it at the end.

See the CornerRadius attribute on the Border? That’s what allows me to have rounded corners. The bigger the number, the greater the rounding.

See the Style.Triggers where I handle the classic MouseOver effect? You can do anything, of course, but I color them orange. It’s the IsMouseOver property that you want to test.

You get this:

image 

 

Making the Header Collapse

Let’s say you want the Header to expand and collapse. We’ll need to make a few changes. Specifically, we must use a ControlTemplate instead of a DataTemplate for the Header.

Unfortunately, this is not possible using ItemsControl. We need to switch to ListView. They are from the same base class. Then we update ItemsControl.GroupStyle like this:

image

See the ContainerStyle? That’s where I am injecting the template name. But our current HeaderTemplate is a DataTemplate and that is not right. We’ll need to change it like this:

image

When the UI does what we want:

image

And when you look at the code, there really isn’t a lot. Not even a lot of XAML. But there sure is a lot of opportunity to mess it up or get the syntax wrong. But once you have it, it’s beautiful.

 

Warning

If you are like me, and I hope you are not, then you might occasionally get this error:

“Operation is not valid while ItemsSource is in use”

Although it seems that the error message is a little to “generic” it typically means that there is a syntax error in the way you have the XAML configured. If you get that, then double-check your XAML. Odds are, you have something typed wrong or in the wrong location or something.

Good hunting.

Here’s the code: You’re Welcome 
(64k zip of the whole solution)