To format a bound item you need to use a class that implements the IValueConverter interface.
First lets create a simple class to bind to
public class BindTo : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
private string _Name;
public string Name
{
get
{
return _Name;
}
set
{
if (value != _Name)
{
_Name = value;
NotifyPropertyChanged("Name");
}
}
}
private double _Price;
public double Price
{
get
{
return _Price;
}
set
{
if (value != _Price)
{
_Price = value;
NotifyPropertyChanged("Price");
}
}
}
}
Now lets create the IValueConverter to display the price as currency. The convert has 2 functions we must implement Convert and ConvertBack. In covert we will convert the decimal to a string. In the convertBack we will remove the $ so the text can be converted to a decimal
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Data;
using System.Globalization;
namespace SilverlightApplication8
{
public class CurrencyConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
double d;
if (double.TryParse(value.ToString(), out d))
{
if (d >= 0.0)
{
return d.ToString("c");
}
}
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
double d;
string s = value.ToString();
if (s.StartsWith("$"))
{
s = s.Substring(1);
}
if (double.TryParse(s, out d))
{
return d;
}
return value;
}
}
}
To use an IValueConverter we need to register it as a StaticResource for the page
<UserControl.Resources>
<local:CurrencyConverter x:Key="MyConverter"></local:CurrencyConverter>
</UserControl.Resources>
In the binding we can specify the converter
<TextBox Text="{Binding Price, Mode=TwoWay, Converter={StaticResource MyConverter}, NotifyOnValidationError=true, ValidatesOnExceptions=true}" Grid.Column="1" Grid.Row="1" Margin="5,5,5,120"></TextBox>
Pages complete xaml
<UserControl x:Class="SilverlightApplication8.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SilverlightApplication8"
Width="400" Height="300">
<UserControl.Resources>
<local:CurrencyConverter x:Key="MyConverter"></local:CurrencyConverter>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Text="Product Name" Grid.Column="0" Grid.Row="0"></TextBlock>
<TextBlock Text="Unit Price" Grid.Column="0" Grid.Row="1"></TextBlock>
<TextBox Text="{Binding Name, Mode=TwoWay}" Grid.Column="1" Grid.Row="0" Margin="5,5,5,120"></TextBox>
<TextBox Text="{Binding Price, Mode=TwoWay, Converter={StaticResource MyConverter}, NotifyOnValidationError=true, ValidatesOnExceptions=true}" Grid.Column="1" Grid.Row="1" Margin="5,5,5,120"></TextBox>
</Grid>
</UserControl>
Here is the code for page which creates the object and binds it
public partial class Page : UserControl
{
BindTo b = new BindTo();
public Page()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(Page_Loaded);
}
void Page_Loaded(object sender, RoutedEventArgs e)
{
b.Name="Apple Juice";
b.Price = 1.39;
LayoutRoot.DataContext = b;
}
}