:New WPF 3.5 SP1 feature: Data Formatting (with Binding.StringFormat)

Background

Formatting data can be a pretty cumbersome task in WPF. To illustrate with a very simple example, let's say I want to display the dollar value of some item in a TextBlock:

<StackPanel>

           <TextBlock Text="Choose a number:"></TextBlock>

           <ComboBox Name="myComboBox" SelectedIndex="0">

                 <ComboBoxItem>

                       <sys:Double>168.361</sys:Double>

                 </ComboBoxItem>

                 <ComboBoxItem>

                       <sys:Double>456.9832</sys:Double>          

           </ComboBoxItem>

           </ComboBox>

           <TextBlock>

                 <TextBlock.Text>

                             <Binding ElementName="myComboBox" Path="SelectedItem.Content"/>

                 </TextBlock.Text>

           </TextBlock>

</StackPanel>

To add in a $ symbol and/or any other formatting, I would need to write my own ValueConverter and do the formatting there.

 <!--added to resource section-->

<local:MoneyConverter x:Key="moneyConverter" />

<!--inside StackPanel-->

<TextBlock>

           <TextBlock.Text>

                <Binding ElementName="myComboBox" Path="SelectedItem.Content" Converter="StaticResource moneyConverter"/>

           </TextBlock.Text>

</TextBlock>

public class MoneyConverter : IValueConverter
{

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

   {

       return string.Format("Item cost: {0:C}", value);

   }

 

   // ConvertBack left out

 }  

nice if I could just include the formatting as a definition with my binding. It would be more readable and self-documenting, as well as decrease the number of ValueConverter classes that I would need to write (which may not be very reusable in the rest of your application). Well, as it turns out this feature has been added in WPF 3.5 SP1.

What is it?

Strings can now be formatted directly in bindings, multibindings and many controls by String.Format(IFormatProvider, String, Object[]).  Note that string formatting is only applied in the direction from source to target.  Anytime the source is updated, the converter/formatting will be reapplied. 

Examples

Single binding standard:

<TextBlock>

           <TextBlock.Text>

                       <Binding ElementName="myComboBox" Path="SelectedItem.Content" StringFormat="Item cost: {0:C}"/>

           </TextBlock.Text>

</TextBlock>  

<TextBlock Text="{Binding ElementName=myComboBox, Path=SelectedItem.Content,     StringFormat=Item cost: {0:C}}"/>  

Single binding convenience:

<TextBlock>

           <TextBlock.Text>

                       <Binding ElementName="myComboBox" Path="SelectedItem.Content" StringFormat="C"/>

           </TextBlock.Text>

</TextBlock>

<TextBlock Text="{Binding ElementName=myComboBox, Path=SelectedItem.Content,     StringFormat=C}"/>     

Single binding escaping markup:

注意"{}{0:C}"是一种格式,前缀{}表示在格式化后的字符串前面不加任何附加的字符。

<TextBlock>

           <TextBlock.Text>

                       <Binding ElementName="myComboBox" Path="SelectedItem.Content" StringFormat="{}{0:C}"/>

           </TextBlock.Text>

</TextBlock>

 

下面是是另一种写法,注意与上面写法的区别是值没有加””, 例如ElementName="myComboBox"

ElementName=myComboBox由于StringFormat含有字符’{’’}’,所以要用转义符’\’

<TextBlock Text="{Binding ElementName=myComboBox, Path=SelectedItem.Content,     StringFormat=\{0:C\}}"/>     

Formatting in DisplayMemberBinding:

<GridViewColumn Header="Price" DisplayMemberBinding="{Binding Path=Price, StringFormat=C}"/>

MultiBinding:

<TextBlock>

           <TextBlock.Text>

                 <MultiBinding StringFormat="Item1 cost: {0}, Item2 cost: {1}">

                       <Binding ElementName="myComboBox" Path="SelectedItem.Content"/>

                       <Binding ElementName="myComboBox2" Path="SelectedItem.Content"/>

                 </MultiBinding>

           </TextBlock.Text>

</TextBlock>

MultiBinding with a converter (note that the converter is called before the string is formatted):

<TextBlock>

           <TextBlock.Text>

                 <MultiBinding Converter="{StaticResource sumConverter}" StringFormat="Total Item cost: {0}">

                       <Binding ElementName="myComboBox" Path="SelectedItem.Content"/>

                       <Binding ElementName="myComboBox2" Path="SelectedItem.Content"/>

                 </MultiBinding>

           </TextBlock.Text>

</TextBlock>

Many controls have also added a new property to set format on its content.  For example, ContentControl has added ContentStringFormat,  HeaderedContentControl has added HeaderStringFormat, and ItemsControl has added ItemStringFormat.  These are only a few examples.               

<Label ContentStringFormat="dddd – d - MMMM">

     <sys:DateTime>2004/3/4 13:6:55</sys:DateTime>

</Label>

 

<Button ContentStringFormat="{}{0:MM/dd/yyyy}">

           <sys:DateTime>2004/3/4 13:6:55</sys:DateTime>

</Button>  

 

“F1”表示只显示一位小数。

<ListBox Name="lb1" SelectedIndex="1" ItemStringFormat="F1">

           <sys:Double>3.14159</sys:Double>

           <sys:Double>2.71828</sys:Double>

</ListBox>

  

你可能感兴趣的:(String)