Mindscape Mindblog

Archive for the ‘WPF’ Category

WPF Elements 2.0 is here!

tag icon Tagged as WPF, WPF Elements

We’re proud to announce the release of WPF Elements 2.0, the latest version of our package of controls for Windows Presentation Foundation. WPF Elements 2.0 includes four great new controls to quickly provide an even richer user experience to your applications, five good looking themes based on Microsoft Office and Expression Blend and many enhancements to the Elements 1.0 controls.

CoverFlow

CoverFlow is a list control that presents the selected item front and centre, with the unselected items arranged in a pseudo-perspective view around it. It provides a visually attractive and nicely animated way to present visual collections such as collections of photos, pictures or charts.

You can read more about CoverFlow, with link to a live demo, here.

ColorPicker

The ColorPicker control allows users to select colors in three different ways:

  • Standard colors: a list of the built-in WPF colors displayed as a list of swatches along with their common names.
  • Custom colors: allows users to mix their own colors using sliders or text boxes to specify the red, green, blue and alpha channels.
  • Palette mode: similar to the color picker seen in Microsoft Office. This allows you to define the palette for your application so as to encourage users towards choices that work well together. You can customise the palette contents, arrangement and tooltips.

Here’s the palette view, showing a colour palette appropriate for modern graphic designs:

Here’s the custom color mode that gives the user full control to mix their own color. The colors on each of the sliders change dynamically making it very easy to see how changing each color channel will affect the result.

By providing your own style for the ColorPicker control, you can define which modes are available, style each mode however you like, or even have the ColorPicker displayed inside a window instead of a drop down.

AutoCompleteBox

The AutoCompleteBox helps to save typing and reduce errors by providing users with suggestions as they type. The user can quickly choose a suggestion with the arrow keys and thus “auto-complete” their entry.

To avoid confusing the user with too many suggestions, you can configure the AutoCompleteBox to limit the maximum number of suggestions to display at a time, and also not to display any suggestions until the user has typed a reasonable number of characters. You can also implement your own suggestion provider to perform custom matches, for example against custom sources such as the file system or using custom strategies such as matching initials (e.g. for WL suggest WriteLine).

PromptDecorator

This control can be attached to other controls to display a prompt telling the user what the control is for. The prompt is overlaid on the other control, conserving screen space and giving a smooth modern appearance, but disappears when the user clicks on the control so as to keep the control free of clutter when the user wants to type into it. The PromptDecorator can easily be styled to customize the look of the prompt allowing it to display images as well as text.

Here is the PromptDecorator being used in 4 different ways. The first one is simply being applied to a TextBox. The second one is also applied to a TextBox, but has been given a custom prompt template to include the magnifying glass. The next one shows the PromptDecorator being applied to an editable ComboBox. And the last one is being applied to the AutoCompleteBox.

Take it for a spin

If you have .NET 3.5 installed and want to have a play around with all of the controls included in WPF Elements, then you can see it live here. This also shows the cool new themes. You can also download a trial copy to try it out in your own applications.

We are always open for suggestions for improving these controls or ideas of more controls that you want to see. Put up a post on our forum and let us know!

WPF Diagrams: Custom Diagram Node Data

tag icon Tagged as WPF, WPF Diagramming

You may know that in WPF Flow Diagrams you can create your own custom node types to hold any additional data that they need. These nodes can be styled however you want, and also can be integrated into the serialization and undo features. This is useful when you want to create your own kind of node to represent a specific process that has its own attributes.

But what if you have various kinds of data objects that you want to be held by any type of diagram node? Or maybe you’re happy with the standard node types that we provide, but want them to hold more data without creating your own node types? Say for example you are creating a diagram where each node represents a task involved in completing a project. You may want each node including start and end nodes to contain text, as well as a list of people responsible for completing the task. Sure, you could create some custom node types that contain this additional data, but it would be nice if we could simply use the node’s Data property to hold any data we need

This has always been possible, but in the past it’s been slightly problematic due to the standard styles and serializer assuming that nodes only hold string content. However, if you download the latest update of WPF Flow Diagrams, you will find it is now easier to allow any kind of node to hold any kind of custom data that you need.

So you have some custom data objects that you want to be held by any node in a diagram. There are 2 main things you need to do: tell the diagram surface how to display the data content of a node, and tell the serializer how to serialize and deserialize your data objects.

Custom node content templates

The IDiagramFormatter interface now contains a property called NodeContentTemplateSelector. This can be set up to select a DataTemplate based on both the type of a diagram node, and the type of data that it holds. So you can have all nodes displaying each type of custom data the same way, or start nodes could display data differently to end nodes. So for each of the different types of node content that you want to display, you need to create a DataTemplate. These data templates will be templating your custom data, so you can have bindings to properties in your data objects to make them look however you want. Set these data templates into whatever data template selector you need, and set the selector into the NodeContentTemplateSelector of the IDiagramFormatter your using.

Here is an example of the effects you can achieve with templating custom node content.
(You can download this sample here to see how it works. Make sure you’ve also downloaded the latest update of WPF Flow Diagrams)

The start node simply contains a string. It gets a default template containing a TextBox where the text is a binding to the Data property of the node.

The next node contains custom data that has a string and an arbitrary object. The template selected for this type of node content displays the string but nothing else. This is useful when you want nodes to store custom data, but don’t want to change the appearance of the node.

The next node contains custom data that has a string and some data that represents a square. The template selected for this type of data displays the string, and also a coloured square. The template could also use attributes from the data to change the apperance of the square. For example its size and colour.

The last 2 nodes are different, but contain the same type of data. I have set up the template selector to use a different DataTemplate depending on the type of node ignoring the fact that the type of data is the same.

Custom node content serialization

Serializing your own custom data objects is fairly straight forward. IFlowDiagramSerializer now has a NodeContentSerializer property. All you need to do is make your own implementation of the new INodeContentSerializer interface. In the serialize method, you are given the data object that needs to be serialized. If you are serializing to XML, you just need to use the given XmlWriter to write any attributes your data objects have. If you have more than one type of custom data object, then you should also write some kind of attribute to the XmlWriter that indicates what type of data you are writing.

Now in the deserialize method, you get an XmlReader, and need to return an object. If you have multiple types of data objects, then you will first want to find out what type of object you are deserializing. This can be done by checking the value of the previously mentioned attribute. When you know what you are deserializing, you can read the values of the attributes that you wrote to XML, and create an instance of your data object based on these values.

If you haven’t tried the WPF Flow Diagrams yet and want to create some very slick looking diagrams then download the trial version now and let us know what you think!

WPF Themes

Today we have released our stylish new product: WPF Themes. Using these themes you can quickly get your applications looking attractive and modern with very little work involved.

Office 2007 Blue Theme

If you have .Net 3.5 installed and your browser supports XBAPs then you can try out all the themes right here.

The pack includes themes based on the Microsoft Office and Expression applications so your users will find them familiar and easy to use.

WPF Themes comes with documentation to help you get started quickly, and a few samples demonstrating how to apply a theme to your applications. The samples can also be used to view how the themes look on all the various controls that they support.

Plus, if you’re looking to make your own themes for your WPF applications, WPF Themes is a great way to help you get started. The themes are provided as source code, so you can simply copy whichever theme you like, and modify it to suit your needs. All the XAML files are well structured containing easily noticed comments making it easy to find the style for the control you want to see. Across all five themes, the order of the styles are kept the same which makes it easy to compare them.

WPF Themes is available to try out and buy today. Mega Pack customers will find WPF Themes available for download in the next few days.

Using WPF PropertyGrid or WPF Elements? The WPF Property Grid already includes two of these themes, and we’ll be shipping the remaining WPF Property Grid themes plus all five themes for Elements over the next few days.

If you have any queries about WPF Themes, or want help or advice with making your own themes then we would love to hear from you. Simply put a comment up on our WPF Themes support forum.
Happy styling =)

kick it on DotNetKicks.com

WPF Coverflow control released

tag icon Tagged as WPF, WPF Elements

Mindscape WPF Elements Logo

I’m pleased to announce that we have just released a control that allows WPF developers to create a coverflow effect similar to what is available in iTunes.

Here’s a screenshot of the control in action:

WPF Coverflow in action

So what can I do with it?

The control is very configurable and at a high level allows you to:

  • Configure the size of the covers
  • Alter the size or existence of the reflections
  • Completely customise the look and feel of the covers with standard WPF styling techniques
  • Alter the spacing between covers
  • Alter the tilt of the covers

The control also works with all standard WPF capabilities – for example, binding to an ItemsSource property for the collection of covers. One other very cool feature is controlling what’s displayed on the cover – it can be any UIElement meaning you can host a video, image, other controls, whatever you want really!

How do I get it?

Here’s the great news – all customers of Mindscape WPF Elements already have it! We baked it into the nightly builds once it was polished and ready for release. If you’re a customer you can get it right now by clicking here.

If you’re not a customer but would like to test out the WPF Coverflow control, download the free trial of WPF Elements here (note, you must use the latest nightly, we will be bundling this into a final release version soon).

You can also see the WPF Coverflow control in action live within your browser by clicking here (requires .NET Framework 3.0 SP1 installed for XBAP support).

Let us know what you think!

Attached behaviours in WPF

tag icon Tagged as WPF

WPF is all about composition. Good WPF code is made up of lots of small, specific, reusable components — things like value converters, commands, styles and selectors — brought together with XAML. However, one area where there’s no obvious built-in means of composition is behaviour. You can’t style event handling the way you can style appearance. So traditionally, customising the behaviour of a control means writing a new control (though hopefully reusing the existing one!). This is a bit heavyweight, and leads to a combinatoric explosion if you have a bunch of optional behaviours which you want to be able to turn on and off on a case-by-case basis.

Attached behaviours are a solution to this problem. Using attached behaviours, you can bundle up a piece of event-handling logic in a small, specific, reusable package which you can then apply to controls using XAML — even using styling!

Let’s consider a simple example. Suppose we want to create a text box that only allows the user to enter digits. We could of course hook the PreviewTextInput event and block all non-digit input:

<TextBox PreviewTextInput="TextBox_PreviewTextInput" />
private void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
  foreach (char ch in e.Text)
    if (!Char.IsDigit(ch))
      e.Handled = true;
}

This approach works fine as a specification of behaviour for that one specific text box, but it’s not reusable or composable. First, the event handler has to be in the code-behind for the window, so if we want digit-only text boxes in another window, we end up duplicating the code. Second, we can’t compose this with other behaviour that triggers on the PreviewTextInput event: a control can’t have two handlers for the same event. Third, if there’s logic that depends on multiple events (say, a key-down/key-up pair), the behaviour is no longer atomic: we might remember to hook up the key-down event but forget the key-up event. Fourth, it can’t be hooked up to the control using the normal WPF customisation system of styles and templates.

The solution is to rework the event handling code as an attached behaviour. An attached behaviour is simply an attached property that, when it is set on an object, does something to that object. (As distinct from typical attached properties, which just associate some data with the object for something else to consume. In fact, attached behaviours may be totally uninterested in the value of the property they’re masquerading as — they may care only about who they’re being attached to.) Attached behaviours work their magic in the property changed callback, which is called by WPF when the value of the property on an object changes — of greatest interest, when the value of the property on an object is first set. Let’s take a look, starting with the attached property boilerplate.

public static class InputBehaviour
{
  public static bool GetIsDigitOnly(DependencyObject obj)
  {
    return (bool)obj.GetValue(IsDigitOnlyProperty);
  }
 
  public static void SetIsDigitOnly(DependencyObject obj, bool value)
  {
    obj.SetValue(IsDigitOnlyProperty, value);
  }
 
  public static readonly DependencyProperty IsDigitOnlyProperty =
    DependencyProperty.RegisterAttached("IsDigitOnly", 
    typeof(bool), typeof(InputBehaviour), 
    new UIPropertyMetadata(false, OnIsDigitOnlyChanged));
}

There’s nothing unusual going on here — this is a completely boilerplate attached property definition, straight out of the Visual Studio snippet except for the addition of a property changed callback named OnIsDigitOnlyChanged. What does that callback look like?

private static void OnIsDigitOnlyChanged(object sender, DependencyPropertyChangedEventArgs e)
{
  // ignoring error checking
  TextBox textBox = (TextBox)sender;
  bool isDigitOnly = (bool)(e.NewValue);
 
  if (isDigitOnly)
    textBox.PreviewTextInput += BlockNonDigitCharacters;
  else
    textBox.PreviewTextInput -= BlockNonDigitCharacters;
}
 
private static void BlockNonDigitCharacters(object sender, TextCompositionEventArgs e)
{
  foreach (char ch in e.Text)
    if (!Char.IsDigit(ch))
      e.Handled = true;
}

What’s going on here? When InputBehaviour.IsDigitOnly is set on a TextBox, if it’s being set to true, we hook up the TextBox’s PreviewTextInput event (giving it the same handler as in the original example). If it’s being set to false, we remove that event handler. So what happens when WPF loads the following XAML?

<TextBox local:InputBehaviour.IsDigitOnly="True" />

As WPF loads the XAML, it sets the InputBehaviour.IsDigitOnly property to true on the TextBox. That in turn triggers the property changed callback. And that in turn hooks up the TextBox’s PreviewTextInput event so that it will reject all non-digit input. We’ve got the same behaviour we had in the original one-off event handling example, but now it’s in a nicely packaged, reusable form. We can set IsDigitOnly on text boxes from different windows. We can compile the InputBehaviour class into a library and reuse it from other assemblies, in pure XAML. We can compose it with other behaviours and we can even bundle it up in a style:

<Window.Resources>
  <Style x:Key="BigHonkingDigitOnlyTextBox" TargetType="TextBox">
    <Setter Property="FontSize" Value="36" />  <!-- big -->
    <Setter Property="local:InputBehaviour.HonkOnKeyPress" Value="True" />  <!-- honking -->
    <Setter Property="local:InputBehaviour.IsDigitOnly" Value="True" />  <!-- digit-only -->
  </Style>
</Window.Resources>
 
<StackPanel>
  <TextBox Margin="10" Style="{StaticResource BigHonkingDigitOnlyTextBox}" />
</StackPanel>

If you want to learn more, there’s a reasonable amount of material out there about attached behaviours, describing implementation techniques and going much further into possible applications than I’ve discussed here. Josh Smith’s blog is a good place to start, and John Gossman has an article about how it’s applied in Expression Blend. At any rate, it’s a handy trick and a good way to refactor repetitive event handling code. And the same technique can also be used for some other neat little tricks. We’ll talk about those in a future article.