3

In some of my projets, I sometime do things like

TxtBox.Text = 10000.ToString("#,0.00") ' TxtBox.Text content = 10 000.00

However, if I have a DataGridTextBoxColumn with binding like this :

{Binding Amount,StringFormat='#,0.00'}

The value shown is 10,000.00 and not 10 000.00

I tried changing both the UI culture and Culture and the application startup but I can only change the way it appears when I use code and not in the binding. Is there any way to make this work ? Is there a 'BindingCulture' of some sort ???

Edit, here is an example of DataGrid I have

<DataGrid x:Name="GridModules" Grid.Column="0" ItemsSource="{Binding}" Style="{StaticResource BaseGrid}" IsTabStop="False">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Nom" Width="*"  MinWidth="150"
                                               Binding="{Binding Nom}"                                               
                                               IsReadOnly="True" />
        <DataGridTextColumn Header="Prix" Width="120"  MinWidth="100"
                                               Binding="{Binding PrixAvantTaxe, StringFormat='#,0.00'}"
                                               CellStyle="{StaticResource RightCellStyle}"
                                               IsReadOnly="True" />
        <DataGridCheckBoxColumn Header="Révisé" Width="100"  MinWidth="100"
                                                Binding="{Binding EstRevise}"                                                      
                                                IsReadOnly="True" />
    </DataGrid.Columns>
</DataGrid>

Edit : I think my question is misunderstood. I would like to get 10 000.00, which is what I get when I use code and NOT 10,000.00, which is what I get when I use binding in datagrids.

5
  • Have you tried? {Binding Amount,StringFormat={}{0:#,0.00}} Commented Dec 1, 2011 at 13:22
  • This in itself does not compile because of the ',', but I will try with '' and gives you the result Commented Dec 1, 2011 at 13:35
  • Even with '' it doens't make any difference Commented Dec 1, 2011 at 13:38
  • What is RightCellStyle? This is most likely causing your problem. You my be looking for ElementStyle and EditingElementStyle. Commented Dec 1, 2011 at 14:53
  • It did work but I need to put ### ### ### #0.00 if I want more than one space, which is ok on this case but I don't really like it because I don't unserstant why the other way does not work. Commented Dec 1, 2011 at 15:21

3 Answers 3

1

Ok it seems that this amounts to pretty much a formatting question. If you know a specific Culture which uses teh space character as it's NumberGroupSeparator You could use that culture; otherwise, the following example ripped right from the msdn link provided should help:

   public static void Main() {

      // Gets a NumberFormatInfo associated with the en-US culture.
      NumberFormatInfo nfi = new CultureInfo( "en-US", false ).NumberFormat;

      // Displays a value with the default separator (",").
      Int64 myInt = 123456789;
      Console.WriteLine( myInt.ToString( "N", nfi ) );

      // Displays the same value with a blank as the separator.
      nfi.NumberGroupSeparator = " ";
      Console.WriteLine( myInt.ToString( "N", nfi ) );

   }

You can do something like the above in an IValueConverter and you can then specify the original format you provided.

Edit This should work.

public class NumberFormatConverter: IValueConverter {        
    public string GroupSeperator { get; set; }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
        if (value == null) return DependencyProperty.UnsetValue;
        var type = value.GetType();
        var stringFormat = parameter as string;
        if (IsNumeric(type)) {
            if (stringFormat == null) {
                return value.ToString();
            }
            var formattible = (IFormattable)value;
            // Gets a NumberFormatInfo associated with the en-US culture.
            NumberFormatInfo nfi;
            if (GroupSeperator == null) {
                nfi = culture.NumberFormat;
            } else {
                nfi = ((CultureInfo) culture.Clone()).NumberFormat;
                nfi.NumberGroupSeparator = GroupSeperator;                
            }
            return formattible.ToString(stringFormat, nfi);
        }
        return DependencyProperty.UnsetValue;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
        return DependencyProperty.UnsetValue;
    }

    public static bool IsNumeric(Type type) {
        if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) {
            var elementType = new NullableConverter(type).UnderlyingType;
            return IsNumeric(elementType);
        }
        return
            type == typeof(Int16) ||
            type == typeof(Int32) ||
            type == typeof(Int64) ||
            type == typeof(UInt16) ||
            type == typeof(UInt32) ||
            type == typeof(UInt64) ||
            type == typeof(decimal) ||
            type == typeof(float) ||
            type == typeof(double);
    }
}

And the XAML:

    <DataGrid x:Name="Accounts" ItemsSource="{Binding Accounts}" AutoGenerateColumns="False" AlternatingRowBackground="Azure">
        <DataGrid.Resources>
            <local:NumberFormatConverter x:Key="NumberFormatConverter" GroupSeperator=" " />
            <local:NumberFormatConverter x:Key="UnderScoreNumberFormatConverter" GroupSeperator="_" />
        </DataGrid.Resources>
        <DataGrid.Columns>
            <DataGridTextColumn Header="Name" Binding="{Binding Name}" />
            <DataGridTextColumn Header="Amount" Binding="{Binding Amount, Converter={StaticResource NumberFormatConverter},ConverterParameter='#,0.00'}" />
            <DataGridTextColumn Header="Whole Dollars" Binding="{Binding WholeDollars, Converter={StaticResource UnderScoreNumberFormatConverter},ConverterParameter='#,0.00'}" />
        </DataGrid.Columns>
    </DataGrid>
Sign up to request clarification or add additional context in comments.

Comments

0

Both work fine for me, showing 10,000.00

TestText.Text = 10000.ToString("#,0.00")

<DataGrid ItemsSource="{Binding Test}">
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding TestNumber,StringFormat={}{0:#\,0.00}}" Header="Test1" />
        <DataGridTextColumn Binding="{Binding TestNumber,StringFormat='#,0.00'}" Header="Test2" />
    </DataGrid.Columns>
</DataGrid>

I suspect the problem has something to do with a Label somewhere. WPF Labels come with a ContentStringFormat property, which overrides any StringFormat on the binding.

For example,

<TextBlock x:Name="ThisWorks" 
           Text="{Binding TestNumber,StringFormat={}{0:#\,0.00}}" />

<Label x:Name="DoesNotWork" 
           Text="{Binding TestNumber,StringFormat={}{0:#\,0.00}}" />

<Label x:Name="Works" 
           Content="{Binding TestNumber}" 
           ContentStringFormat="#,0.00" />

I would suggest downloading Snoop and seeing if that is the case. If so, switch your Labels to TextBlocks, or set your Label's ContentStringFormat to apply formatting

4 Comments

As you pointed out ContentControls need ContentStringFormat set instead of StringFormat.
The point is that it should NOT display 10,000.00 but 10 000.00 , which it does when I 'code the format'
@DavidBrunelle #,0.00 formats as 10,000.00 for me, even with the ToString() version. To remove commas, remove the comma from the StringFormat
Try StringFormat='# ##0.00' (I'm assuming you want that space)
0

From this trial below (which works) clearly it is not the binding, but something with how the grid column is displayed. Could you insert a snippet of your grid definition (I'm primarily interested in what kind of column the value is bound to)?

Edit Now assuming a definition like below, this works for me. There is something else at play here.

<DataGrid x:Name="Accounts" ItemsSource="{Binding Accounts}" AutoGenerateColumns="False" AlternatingRowBackground="Azure">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Name" Binding="{Binding Name}" />
        <DataGridTextColumn Header="Amount" Binding="{Binding Amount, StringFormat='# ##0.00'}" />
        <DataGridTextColumn Header="Whole Dollars" Binding="{Binding WholeDollars, StringFormat='# ##0.00'}" />
    </DataGrid.Columns>
</DataGrid>

Edit Now that you have shown your definition I'm fairly sure it's your CellStyle which is breaking this. What is RightCellStyle? Did you mena to use ElementStyle or EditingElementStyle?

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.