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.
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). |
Post a comment