简体   繁体   English

如何在WPF C#中的数据绑定DataGrid中将字符串格式设置为货币格式?

[英]How can i format a string as currency in a data bound DataGrid in WPF C#?

I have some data being shown in a DataGrid. 我有一些数据显示在DataGrid中。 The data comes from SQL, where a "money" type can be null. 数据来自SQL,其中“金钱”类型可以为null。 When i display this data, all is OK when i format the data in a double column format as currency. 当我显示此数据时,当我以双列格式将数据格式化为货币时,一切正常。 ie: 即:

internal void FillGrid() { 内部void FillGrid(){

        bD = new DataTable();
        DataTable dt = EmployerQuery();  //queries the SQL DB


        bD.Columns.Add(new DataColumn("ID", typeof(int)));
        bD.Columns.Add(new DataColumn("EmployerName", typeof(string)));
        bD.Columns.Add(new DataColumn("FlatMinAmount", typeof(double)));
        bD.Columns.Add(new DataColumn("DistrictRate", typeof(double)));
        bD.Columns.Add(new DataColumn("VendorRate", typeof(double)));
        bD.Columns.Add(new DataColumn("Description", typeof(string)));
        bD.Columns.Add(new DataColumn("EmployeeCount", typeof(int)));

        foreach (DataRow sqlRow in dt.Rows)
        {
            var row = bD.NewRow();
            row["ID"] = sqlRow["ClientID"];
            row["EmployerName"] = sqlRow["OfficialName"];
            row["FlatMinAmount"] = sqlRow["FlatMinAmount"];
            row["DistrictRate"] = sqlRow["DistrictRate"];
            row["VendorRate"] = sqlRow["VendorRate"];
            row["Description"] = sqlRow["Description"];
            row["EmployeeCount"] = sqlRow["EmployeeCount"];

            bD.Rows.Add(row);

        }    

However, I then save the data as a .csv file. 但是,然后将数据另存为.csv文件。 When i read that file back, the values for "FlatMinAmount" that were null are not allowed to be inserted into a column type double, so I cannot format the data columns as type double, since many are null. 当我读回该文件时,不允许将null的“ FlatMinAmount”值插入到double类型的列中,因此我无法将数据列格式化为double类型,因为许多字段为null。

<dg:DataGrid Name="newGrid" ItemsSource="{Binding ElementName=readGrid, Path=readGrid}" AutoGenerateColumns="False"
                 Margin="5" Height="175" Width="Auto" ColumnWidth="Auto">
        <dg:DataGrid.Columns>
            <dg:DataGridTextColumn Binding="{Binding ID}" Header="Employer ID" Width="Auto" IsReadOnly="True"/>
            <dg:DataGridTextColumn Binding="{Binding EmployerName}" Header="Employer Name" Width="Auto" IsReadOnly="True"/>
            <dg:DataGridTextColumn Binding="{Binding FlatMinAmount, StringFormat=C}" Header="FlatMinAmount" Width="Auto" IsReadOnly="True"/>
            <dg:DataGridTextColumn Binding="{Binding DistrictRate, StringFormat=C}" Header="District Rate" Width="Auto" IsReadOnly="True"/>
            <dg:DataGridTextColumn Binding="{Binding VendorRate, StringFormat=C}" Header="Vendor Rate" Width="Auto" IsReadOnly="True"/>
            <dg:DataGridTextColumn Binding="{Binding Description}" Header="Description" Width="Auto" IsReadOnly="True"/>
            <dg:DataGridTextColumn Binding="{Binding EmployeeCount}" Header="EmployeeCount" Width="*" IsReadOnly="True"/>
        </dg:DataGrid.Columns>
    </dg:DataGrid>


DataTable r = new DataTable();

        try
        {
            //string csv = string.Empty;

            //r.Columns.Add("ID", typeof(int));
            //r.Columns.Add("EmployerName", typeof(string));
            //r.Columns.Add("FlatMinAmount",typeof(double));
            //r.Columns.Add("DistrictRate", typeof(double));
            //r.Columns.Add("VendorRate", typeof(double));
            //r.Columns.Add("Description", typeof(string));
            //r.Columns.Add("EmployeeCount", typeof(int));

            r.Columns.Add("ID");
            r.Columns.Add("EmployerName");
            r.Columns.Add("FlatMinAmount");
            r.Columns.Add("DistrictRate");
            r.Columns.Add("VendorRate");
            r.Columns.Add("Description");
            r.Columns.Add("EmployeeCount");

            // Read sample data from CSV file
            using (CsvFileReader reader = new CsvFileReader(filename))
            {
                CsvRow row = new CsvRow();
                while (reader.ReadRow(row))
                {
                    //foreach (string s in row)
                    {
                        r.Rows.Add(row[0], row[1], row[2], row[3], row[4], row[5], row[6]);


                    }

                }
            }

(readGrid is then set to r in code-behind) (然后在代码后面将readGrid设置为r)

If they are string, then i cannot use the StringFormat=C in the binding to show $ etc. Also, it seems I cannot style a DataGridTextColumn. 如果它们是字符串,那么我不能在绑定中使用StringFormat = C来显示$等。而且,看来我无法设置DataGridTextColumn的样式。 So, how can i display the values I read in from .csv as $xx.xx? 那么,如何显示从.csv读取的值作为$ xx.xx?

use Double.Parse() - http://msdn.microsoft.com/en-us/library/system.double.parse.aspx to format the value when you read it in. This will allow you to use double and you can then apply the appropriate formatting for output. 使用Double.Parse() : //msdn.microsoft.com/zh-cn/library/system.double.parse.aspx读取值时格式化该值。这将允许您使用double并可以然后将适当的格式应用于输出。

Updated: The issue you seem to be having that when reading from file the value is null and when reading from database it is DBNull . 已更新:您似乎遇到的问题是,从文件读取时该值为null而从数据库读取时为DBNull By default DataTable allows for DBNull values. 默认情况下, DataTable允许使用DBNull值。 If you want to mimic this for read, try the following 如果您想模仿此内容以供阅读,请尝试以下操作

    DataTable r = new DataTable();
    try
    {
        r.Columns.Add("ID");
        r.Columns.Add("EmployerName");
        r.Columns.Add("FlatMinAmount");
        r.Columns.Add("DistrictRate");
        r.Columns.Add("VendorRate");
        r.Columns.Add("Description");
        r.Columns.Add("EmployeeCount");

        // Read sample data from CSV file
        using (CsvFileReader reader = new CsvFileReader(filename))
        {
            CsvRow row = new CsvRow();
            while (reader.ReadRow(row))
            {
                //foreach (string s in row)
                {
                    double d;
                    double? val2 = null;
                    double? val3 = null;
                    double? val4 = null;
                    if (Double.TryParse(row[2], out d)) val2 = d;
                    if (Double.TryParse(row[3], out d)) val3 = d;
                    if (Double.TryParse(row[4], out d)) val4 = d;

                    r.Rows.Add(row[0], row[1], val2, val3, val4, row[5], row[6]);
                }

            }
        }

使用TargetNullValue属性:

<dg:DataGridTextColumn Binding=""{Binding FlatMinAmount,TargetNullValue='Not Specified',StringFormat=C}" Header="FlatMinAmount" Width="Auto" IsReadOnly="True"/>

If you know the number is null, can't you just set the value of the column to DBNull? 如果您知道数字为空,就不能仅将列的值设置为DBNull吗?

row["FlatMinAmount"] = DBNull.Value;

Here's a little console app I ran to show this working: 这是我运行的一个小控制台应用程序,以显示其工作原理:

class Program
    {
        static void Main(string[] args) {
            DataTable tbl = new DataTable();
            DataColumn col = new DataColumn("Blah", typeof(double));
            tbl.Columns.Add(col);

            DataRow row = tbl.NewRow();
            row["Blah"] = DBNull.Value;

            Console.WriteLine("Result: " + row["Blah"].ToString());
            Console.ReadKey();

        }
    }

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

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