Reputation: 6440
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.
Upvotes: 3
Views: 3814
Reputation: 2789
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>
Upvotes: 1
Reputation: 2789
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?
Upvotes: 0
Reputation: 132558
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
Upvotes: 0