Formatting Strings with a Value Converter

Value converters are the perfect tool for formatting numbers that need to be displayed as text. For example, consider the Product.UnitCost property in the previous example. It's stored as a decimal, and as a result, when it's displayed in a text box, you'll see values like 3.9900. Not only does this display format show more decimal places than you'd probably like, it also leaves out the currency symbol. A more intuitive representation would be the currency-formatted value $49.99, as shown in Figure 14-8.

Figure 14-8. Displaying formatted currency values

To create a value converter, you need to take three steps:

1. Create a class that implements IValueConverter.

2. Implement a Convert() method that changes data from its original format to its display format.

3. Implement a ConvertBack() method that does the reverse and changes a value from display format to its native format.

Figure 14-9 shows how it works.

Source Object

(Data Object)

f

Property

V

ConvertQ

ConvertBackQ

Target Object (Display Element)

Dependency Property (Set with Binding)

Figure 14-9. Converting bound data

In the case of the decimal-to-currency conversion, you can use the Decimal.ToString() method to get the formatted string representation you want. You simply need to specify the currency format string "C", as shown here:

string currencyText = decimalPrice.ToString("C");

This code uses the culture settings that apply to the current thread. A computer that's configured for the English (United States) region runs with a locale of en-US and displays currencies with the dollar sign ($). A computer that's configured for another local might display a different currency symbol. If this isn't the result you want (for example, you always want the dollar sign to appear), you can specify a culture using the overload of the ToString() method shown here:

Culturelnfo culture = new Culturelnf ("en-US");

string currencyText = decimalPrice.ToString("C", culture);

You can learn about all the format strings that are available in the Visual Studio help. However, Table 14-3 and Table 14-4 show some of the most common options you'll use for numeric and date values, respectively.

Table 14-3. Format Strings for Numeric Data

Type

Format String

Example

Currency

C

$1,234.50.Parentheses indicate negative values: ($1,234.50). The currency sign is locale-specific.

Scientific (Exponential)

E

1.234.50E+004.

Percentage

P

45.6%.

Fixed Decimal

F?

Depends on the number of decimal places you set. F3 formats values like 123.400. F0 formats values like 123.

Table 14-4. Format Strings for Times and Dates

Type

Format String

Format

Short Date

d

M/d/yyyy. For example: 10/30/2005

Long Date

D

dddd, MMMM dd, yyyy. For example: Monday, January 30, 2005

Long Date and Short Time

f

dddd, MMMM dd, yyyy HH:mm aa. For example: Monday, January 30, 2005 10:00 AM

Long Date and Long Time

F

dddd, MMMM dd, yyyy HH:mm:ss aa. For example: Monday, January 30, 2005 10:00:23 AM

ISO Sortable Standard

s

yyyy-MM-dd HH:mm:ss. For example: 2005-01-30 10:00:23

Month and Day

M

MMMM dd. For example: January 30

General

G

M/d/yyyy HH:mm:ss aa (depends on locale-specific settings). For example: 10/30/2002 10:00:23 AM

Converting from the display format back to the number you want is a little trickier. The Parse() and TryParse() methods of the Double type are logical choices to do the work, but ordinarily they can't handle strings that include currency symbols. The solution is to use an overloaded version of the Parse() or TryParse() method that accepts a System.Globaliza-tion.NumberStyles value. If you supply NumberStyles.Any, you'll be able to successfully strip out the currency symbol, if it exists.

Here's the complete code for the value converter that deals with price values like the Product.UnitCost property:

public class PriceConverter : IValueConverter {

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)

double price = (double)value; return price.ToString("C", culture);

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)

string price = value.ToString(); double result;

if ( ouble.TryParse(price, NumberStyles.Any, culture, out result)) {

return result;

return value;

To put this converter into action, you need to begin by mapping your project namespace to an XML namespace prefix you can use in your markup. Here's an example that uses the namespace prefix local and assumes your value converter is in the namespace DataBinding:

xmlns:local="clr-namespace:DataBinding"

Typically, you'll add this attribute to the <UserControl> start tag at the top of your markup.

Now, you simply need to create an instance of the PriceConverter class in the Resources collection of your page, as shown here:

<UserControl.Resources>

<local:PriceConverter x:Key="PriceConverter"></local:PriceConverter> </UserControl.Resources>

Then, you can point to it in your binding using a StaticResource reference, as shown here: <TextBox Margin="5" Grid.Row="2" Grid.Column="1"

Text="{Binding UnitCost, Mode=TwoWay, Converter={StaticResource PriceConverter}}">

Note Unlike WPF, Silverlight lacks the IMultiValueConverter interface. As a result, you're limited to converting individual values, and you can't combine values (for example, join together a FirstName and a LastName field) or perform calculations (for example, multiply UnitPrice by UnitsInStock).

0 0

Post a comment

  • Receive news updates via email from this site