简体   繁体   English

与Stringformat的WPF绑定行为与代码不同?

[英]WPF Binding behaviour with Stringformat different than with code?

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 : 但是,如果我有一个带有这样的绑定的DataGridTextBoxColumn:

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

The value shown is 10,000.00 and not 10 000.00 显示的值是10,000.00而不是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. 我尝试改变UI文化和文化以及应用程序启动,但我只能改变它在使用代码时出现的方式,而不是在绑定中。 Is there any way to make this work ? 有没有办法让这项工作? Is there a 'BindingCulture' of some sort ??? 是否存在某种“BindingCulture”?

Edit, here is an example of DataGrid I have 编辑,这是我拥有的DataGrid的一个例子

<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. 我想获得10 000.00,这是我使用代码而不是10,000.00时得到的,这是我在datagrids中使用绑定时得到的。

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; 如果你知道一个特定的文化,它使用空格字符,因为它是NumberGroupSeparator你可以使用这种文化; otherwise, the following example ripped right from the msdn link provided should help: 否则,以下示例从提供的msdn链接中直接撕开应该有帮助:

   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. 您可以在IValueConverter执行上述操作,然后指定您提供的原始格式。

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: 和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>

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. 编辑现在您已经显示了您的定义我很确定这是您的CellStyle打破了这一点。 What is RightCellStyle? 什么是RightCellStyle? Did you mena to use ElementStyle or EditingElementStyle ? 你有没有使用过ElementStyleEditingElementStyle

Both work fine for me, showing 10,000.00 两者都适合我,显示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. 我怀疑这个问题与某处的Label WPF Labels come with a ContentStringFormat property, which overrides any StringFormat on the binding. WPF标签带有ContentStringFormat属性,该属性覆盖绑定上的任何StringFormat

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. 我建议下载Snoop并查看是否是这种情况。 If so, switch your Labels to TextBlocks , or set your Label's ContentStringFormat to apply formatting 如果是这样,请将Labels切换为TextBlocks ,或将Label的ContentStringFormat设置为应用格式

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM