Home » Blog

rounded header

Archive for April, 2008

Numeric editors in WPF Elements

tag icon Tagged as WPF, WPF Elements

In a previous post we built a handy treasure locator which allowed users to type in coordinates as well as find them on a map. In that example we relied on users’ good sense not to type in garbage. Sometimes, however, it’s helpful to restrict what users can type. WPF Elements provides several controls to support this. For our example, we can make use of the NumericTextBox. This allows users only to enter decimal numbers: all other input is prevented.

Using the NumericTextBox, we can replace our IMultiValueConverter-based free text editor with the following:

<DataTemplate>
  <StackPanel Orientation="Horizontal">
    <Label Content="Latitude: " />
    <ms:NumericTextBox Value="{Binding Latitude}" />
    <Label Content=" Longitude: " />
    <ms:NumericTextBox Value="{Binding Longitude}" />
  </StackPanel>
</DataTemplate>

This design looks a bit out of place in the DropDownEditBox, though it would be fine on an ordinary form:

Numeric text boxes - raw view

We can easily fix this, though, by adding a border to the DropDownEditBox and removing the border from the text boxes.

We have prevented the user from entering non-numeric values, but they can still enter values that are out of range. Latitude should be in the range -90 to +90, and longitude in the range -180 to +180. NumericTextBox has Maximum and Minimum properties that support this:

<ms:NumericTextBox Value="{Binding Latitude}" Minimum="-90" Maximum="90"
                   BorderThickness="0" VerticalAlignment="Center" />

What would be even nicer for our users is if they didn’t have to type the values at all. We provide the drop-down map for this, but that may not give enough precision. It would be good if, after a user has picked out the rough location on the map, they could then then fine-tune it using “nudge increase” and “nudge decrease” buttons rather than having to edit the rough values.

For this, WPF Elements provides the Spin control. Typically, you’ll databind the Spin control either to the Value property of a numeric control, or to the same underlying data as a numeric control, as follows:

<Label Content="Latitude: " />
<ms:NumericTextBox Value="{Binding Latitude}" Minimum="-90" Maximum="90"
                   BorderThickness="0" VerticalAlignment="Center" />
<ms:Spin Value="{Binding Latitude}" Change="0.01" />

Now the user can use the spin buttons to fine-tune the values:

Numeric text boxes - with spin controls

Using a Spin control alongside a numeric editor or display is such a common pattern that WPF Elements provides a SpinDecorator control that you can wrap around such an editor to automatically give it spinning capability. So we could replace the above with:

<ms:SpinDecorator Change="0.01" BorderThickness="0">
  <ms:NumericTextBox Value="{Binding Latitude}" Minimum="-90" Maximum="90"
         BorderThickness="0" VerticalAlignment="Center" />
</ms:SpinDecorator>

SpinDecorator automatically creates the Spin control and binds its Value, Minimum and Maximum properties to the corresponding properties on the contained editor.

SpinDecorator also adds keyboard-based spinning to the contained control. When the user presses the Up or Down arrow key, SpinDecorator treats those keystrokes as though the user had pressed the up or down spin button. Given this, we might decide that our users would be happy to use the cursor keys to fine-tune the values, and the graphical spin UI just creates clutter. SpinDecorator therefore allows you to hide the graphical spin buttons and restore the original appearance, but now with the cursor keys enabled:

<ms:SpinDecorator Change="0.01" ShowSpinUI="False" BorderThickness="0">
  <ms:NumericTextBox Value="{Binding Latitude}" Minimum="-90" Maximum="90"
         BorderThickness="0" VerticalAlignment="Center" />
</ms:SpinDecorator>

It’s hard to see the effect in a static screenshot:

Numeric text boxes - with cursor-key-only spinning

But you can always try it out yourself — check out IntegerTextBoxStyling.xaml in the WPF Elements samples, or have a play with the DateTimePicker control, which internally uses SpinDecorators with hidden UI.

In this example, we’ve looked at the NumericTextBox. WPF Elements also includes a CurrencyTextBox, which provides currency-based formatting of the value, and IntegerTextBox, which restricts the user to entering integer values. The Spin and SpinDecorator controls work with all three numeric editors, and can also be used with any other control that exposes a databindable decimal or integer property.

Drop-down composite controls with WPF Elements

tag icon Tagged as WPF, WPF Elements

Everybody is familiar with the traditional Windows combo box. Combo boxes are a convenient compromise between list boxes and text boxes because, like a text box, they don’t take up much space on screen, but like a list box, they provide a safe and discoverable user interface for choosing a value — users don’t have to remember what values they’re allowed to type.

The limitation of combo boxes is that they are what WPF calls “items controls.” They’re specifically about selecting from a restricted set of items. So if you want the compact presentation of a combo box, but your data can’t be restricted to a list, you’re out of luck. Examples include a date picker — you can’t provide a list of every date in history, but users like being able to pick the date off a calendar rather than typing it in — or a colour picker — again, you can’t put every possible colour in a list, but users like to select from swatches or colour wheels or using sliders, rather than having to type RGB or CMYK codes.

WPF Elements includes a simple control called the DropDownEditBox which addresses this situation. DropDownEditBox enables you to combine a compact presentation with a more expansive “chooser”, which is usually hidden away but can be dropped down when required. In fact, WPF Elements uses DropDownEditBox to build its own DropDownDatePicker control.

DropDownEditBox is a deliberately dumb control. It doesn’t make any assumptions about the kinds of data that its children are dealing with. This means that, unlike the combo box, it can’t give them any help either. It’s entirely up to the user of DropDownEditBox to appropriate “compact” and “chooser” user interfaces and synchronise their data.

In this example, we’ll build a location selector using DropDownEditBox. Our users will be able to type a location into a text box, or can drop down a map and click on the location they want.

We start out with the skeleton of a DropDownEditBox:

<ms:DropDownEditBox Content="{Binding}">
  <ms:DropDownEditBox.HeaderTemplate>
    <DataTemplate />
  </ms:DropDownEditBox.HeaderTemplate>
  <ms:DropDownEditBox.DropDownTemplate>
    <DataTemplate />
  </ms:DropDownEditBox.DropDownTemplate>
</ms:DropDownEditBox>

Notice that DropDownEditBox has a Content property. This is the data source that the “compact” and “chooser” templates bind to. In this case, my local data context is a Treasure object, which has Latitude and Longitude properties. If Treasure instead had a Location property, I could use that as the Content instead.

Now we create the “compact” presentation:

<ms:DropDownEditBox.HeaderTemplate>
  <DataTemplate>
    <TextBox>
      <TextBox.Text>
        <MultiBinding Converter="{StaticResource CoordinateConverter}" UpdateSourceTrigger="PropertyChanged">
          <Binding Path="Latitude" />
          <Binding Path="Longitude" />
        </MultiBinding>
      </TextBox.Text>
    </TextBox>
  </DataTemplate>
</ms:DropDownEditBox.HeaderTemplate>

This is a plain old text box, with an IMultiValueConverter to translate between the Latitude/Longitude property pair and a textual representation of the form “77 W, 18 N.” The converter is two-way, so that the user can enter coordinates in latitude and longitude format.

Finally, we create the “chooser” presentation. We could go to town on designing a map control, with panning and zooming and all those good good things, but that’s for another day; for this example we’ll assume we have something which has X and Y properties, displays an “X marks the spot” icon at their location and updates them in response to a mouse click. (I’m even going to mostly ignore coordinate translation because the map control isn’t the point of this discussion.) We use this simple control to create our “chooser” drop-down template:

<ms:DropDownEditBox.DropDownTemplate>
  <DataTemplate>
    <local:CoordinateSelector X="{Binding Latitude}" Y="{Binding Longitude}"
                              Background="{StaticResource map}" />
  </DataTemplate>
</ms:DropDownEditBox.DropDownTemplate>

All of this is of course standard WPF data binding: there’s nothing specific to the DropDownEditBox about these templates. What the DropDownEditBox does is link the two together in a combo box-like way. Here’s what the DropDownEditBox looks like when it’s first displayed:

Closed DropDownEditBox

And when the user clicks on the down arrow:

Open DropDownEditBox

And as the user clicks on the map or edits the location in the text box, they can see the results of their action in the other pane. The user gets the familiar combo-box-like experience, but without the restrictions of the combo box data model.

WPF Elements 1.0 released!

Today we shipped WPF Elements 1.0. This is a suite of controls aimed primarily at line of business applications, and fills in some of the gaps in the built-in WPF control set compared to Windows Forms: familiar controls like the MaskedTextBox, numeric editor controls (with up-down support) and DateTimePicker. There’s also a multi-column tree view (aka TreeListView) and a couple of infrastructure controls including a generic drop-down which allows you to create combo-box-like experiences without the ComboBox limitations.

You get get more details about WPF Elements at http://www.mindscape.co.nz/Products/WpfElements/default.aspx.

Over the coming days we’ll be posting on the blog about the WPF Elements controls and how you can leverage and customise them in your applications. JD has already leaked some tasters over in the screenshot gallery — follow the blog over the next few days to see how these were done.

As with all Mindscape products, you’re welcome to try it out before making a decision about purchase. The trial edition includes all the samples and online help, which should give you lots of ideas about how you can use and customise the controls, but check back on the blog for more samples and tips.

We welcome any feedback about this product, and if you have any suggestions for related products that you’d like to see us create, let us know. In the meantime, download the trial and give it a spin!

kick it on DotNetKicks.com

Coming soon: WPF Elements

tag icon Tagged as General, Products, WPF

WPF is a fantastic framework for creating modern rich user experiences, but for those looking to move from Windows Forms development to Windows Presentation Foundation, it is often a challenge.

One of the challenges is the lack of several “line of business” controls that many developers are familiar with in Windows Forms development. WPF Elements aims to help address this issue by providing many of the controls that end users expect as well as saving developers time by not having to create these controls from scratch.

Controls included in Mindscape WPF Elements:

  • Multi-column tree view (aka TreeListView) control
  • Masked text box control
  • Numeric text box controls
    • Currency text box control
    • Integer text box control
    • Numeric text box control
  • Spin (up/down) control
  • DateTime controls
    • DateTime Picker
    • Drop down date picker control
    • Month calendar control
  • Several “infrastructure” controls that you can use to build richer components out of these and other “elements”

We’re confident that this pack will make it easier for developers working on line of business applications to take up WPF with all its design and productivity benefits.

We will be shipping WPF Elements in the very near future, if you would like to be notified please email me and I will let you know as soon as we push the big red “release” button :-)

John-Daniel

5 cool features in LightSpeed 2.0

tag icon Tagged as LightSpeed, Products

We are plowing ahead with our development of LightSpeed 2.0 – our current beta is currently being poked and prodded to ensure it is rock solid and we’re progressing with the remaining features.

Rather than solicit more beta testers (although you can still sign up) I thought I’d list five reasons why we’re excited about LightSpeed 2.0 :)

  1. LINQ everywhere – LINQ to LightSpeed means .Net 3.5 users can leverage the power of LINQ when writing their queries but still use the performance features that we are known for (like Named Aggregates)
  2. Designer support – Full modeling support for your domain models directly from Visual Studio 2008. Drag and drop your tables onto the design surface, have associations automatically set up, easily setup validation attributes on model properties and much more.
  3. Database support – SQL Server, Oracle, PostgreSQL, MySQL and SQLite are all supported. This means that LightSpeed 2.0 will be one of the first data access frameworks that provides LINQ to Oracle, LINQ to PostgreSQL, LINQ to MySQL and LINQ to SQLite!
  4. Command line tools – Some folks prefer using command line tools to generate simple model classes so we have included this as well as the Visual Studio integrated designer support.
  5. The simplest, fastest and most lightweight O/RM for .NET – The right balance of power vs. complexity has always been our focus with LightSpeed and this hasn’t changed for version 2.0. There has been considerable work done to tweak, optimize and enhance much of LightSpeed :-)

We appreciate any feedback you may have (which features you like, what’s missing, what would you need to see to switch from what you’re using, etc).

John-Daniel

Data Products Visual Controls Community Store
LightSpeed ORM
NHibernate Designer
SimpleDB Tools
SharePoint Tools
WPF Elements
WPF Diagrams
Silverlight Elements
Forums
Blog
Register
Login
Subscribe to newsletter
Buy Now
My Account
Volume Discounts
Purchase Orders
Contact Us