【问题标题】:Sorting DataGrid Column as Date将 DataGrid 列排序为日期
【发布时间】:2017-10-17 06:01:48
【问题描述】:

我正在编写一个程序来帮助我的公司跟踪工具校准。我将所有工具都保存在 SQLite 数据库中,该数据库没有将列类型设置为 DATETIME 的选项。因此,为了简单起见,我将日期存储为 M/D/YYYY 格式。

我让模型从数据库中提取工具清单并将填充的表返回给视图模型。

从这里我将 viewmodel 数据表绑定到数据网格,还将每个数据网格列绑定到数据表中的相应列。

我希望用户能够将“校准到期”列从最新到最旧或从最旧到最新进行排序。

问题在于,由于 SQLite 和 DataGrid 控件似乎都没有 DateTime 列的选项,因此数据网格继续将这些作为字符串进行排序。

DataGrid 列设置为 DataGridTextColumns,因为我无法确定模板列是否可以解决此问题,甚至无法确定如何使用。

I.E. :

9/26/2017

9/12/2017

8/5/2017

8/28/2017

我尝试将日期转换为 MM/DD/YYYY 格式,但没有成功。 谁能帮我弄清楚我需要做什么才能对这些日期进行正确排序?

如果这有助于缩小可能的解决方案,我正在使用 Caliburn.Micro 和 SQLite。

CheckOutInModel:

    public DataTable RetrieveToolRoster()
    {
        string db_command = "SELECT [id], [cal_date] FROM inventory WHERE [cal_date] IS NOT NULL ORDER BY [id] ASC;";
        SQLiteConnection db_connection = new SQLiteConnection(Properties.Settings.Default.db_connectionstring);
        SQLiteDataAdapter db_dataAdapter = new SQLiteDataAdapter(db_command, db_connection);
        DataTable tr_dataTable = new DataTable();

        try
        {
            db_connection.Open();
            db_dataAdapter.Fill(tr_dataTable);
            db_connection.Close();
            return tr_dataTable;
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error:\r\n" + ex.Message);
            return null;
        }
    }

CheckOutInViewModel:

    private DataTable _toolRoster;
    public DataTable ToolRoster
    {
        get { return _toolRoster; }
        set
        {
            _toolRoster = value;
            NotifyOfPropertyChange(() => ToolRoster);
        }
    }
    public void PopulateToolRoster()
    {
        CheckOutInModel coim = new CheckOutInModel();
        ToolRoster = coim.RetrieveToolRoster();
    }

CheckOutInView:

    <DataGrid Grid.Column="0"
              ItemsSource="{Binding ToolRoster}"
              Style="{DynamicResource DataGridStandard}">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Tool ID"
                                Width="*"
                                Binding="{Binding id}"/>
            <DataGridTextColumn Header="Calibration Due"
                                Width="*"
                                Binding="{Binding cal_due, StringFormat={}{0:d}}"/>
        </DataGrid.Columns>
    </DataGrid>

谢谢!

解决方案

我将我填写的数据表中的数据转移到一个列表中并返回该列表。

CheckOutInViewModel:

    private List<RosterData> _toolRoster;

    public List<RosterData> ToolRoster
    {
        get { return _toolRoster; }
        set
        {
            _toolRoster = value;
            NotifyOfPropertyChange(() => ToolRoster);
        }
    }

CheckOutInModel:

    public List<RosterData> RetrieveToolRoster()
    {
        string db_command = "SELECT [id], [cal_date] FROM inventory WHERE [cal_date] IS NOT NULL ORDER BY [id] ASC;";
        SQLiteConnection db_connection = new SQLiteConnection(Properties.Settings.Default.db_connectionstring);
        SQLiteDataAdapter db_dataAdapter = new SQLiteDataAdapter(db_command, db_connection);
        DataTable tr_dataTable = new DataTable();

        try
        {
            db_connection.Open();
            db_dataAdapter.Fill(tr_dataTable);
            db_connection.Close();
            List<RosterData> rd = new List<RosterData>();                
            foreach (DataRow dr in tr_dataTable.Rows)
            {
                RosterData rds = new RosterData();
                rds.id = dr[0].ToString();
                rds.cal_date = Convert.ToDateTime(dr[1]);
                rd.Add(rds);
            }
            return rd;
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error:\r\n" + ex.Message);
            return null;
        }
    }

名册数据.cs:

public class RosterData
{
    public string id { get; set; }
    public DateTime cal_date { get; set; }
}

【问题讨论】:

  • 使用 foreach 循环并将每个字符串转换为日期时间。 Convert.ToDateTime(String)
  • 我试过了:DataTable testTable = new DataTable(); foreach (DataRow dr in tr_dataTable.Rows) { testTable.Rows.Add(dr[0], Convert.ToDateTime(dr[1].ToString()); } 不幸的是,这不起作用。
  • 在那个时间点,DataTable 已经有一个字符串类型的列。无需使用适配器加载表,只需定义您自己的类,使用数据读取器读取每条记录并将输入转换为自定义类的正确 DateTime 属性(当然,您需要此自定义类的列表来存储每条记录)

标签: c# wpf sqlite mvvm


【解决方案1】:

只需定义您的自定义类,而不是加载数据表。使用 SQLiteDateReader 并将每条记录转换为自定义类列表的元素

public class RosterData
{
    public int id {get;set;}
    public DateTime cal_date {get;set;}
}

public List<RosterData> RetrieveToolRoster()
{
    string List<RosterData> result = new List<RosterData>();
    string db_command = "SELECT [id], [cal_date] FROM inventory WHERE [cal_date] IS NOT NULL ORDER BY [id] ASC;";
    using(SQLiteConnection db_connection = new SQLiteConnection(Properties.Settings.Default.db_connectionstring))
    using(SQLiteCommand cmd = new SQLiteCommand(db_command, db_connection))
    {
        try
        {
            db_connection.Open();
            using(SQLiteDataReader reader = cmd.ExecuteReader())
            {
                while(reader.Read())
                {
                    RosterData rd = new RosterData()
                    {
                        rd.id = Convert.ToInt32(rd["id"]);
                        rd.cal_date = Convert.ToDateTime(rd["cal_date"]);
                    };
                    result.Add(rd);
               }
           }
           return result;
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error:\r\n" + ex.Message);
            return null;
        }

    }
}

.......

private List<RosterData> _toolRoster;
public List<RosterData> ToolRoster
{
    get { return _toolRoster; }
    set
    {
        _toolRoster = value;
        NotifyOfPropertyChange(() => ToolRoster);
    }
}

【讨论】:

  • 感谢您的回答。我从来没有真正以这种方式处理数据,但正在考虑将您的答案与我的代码集成。如果我将其插入并工作,我会将您标记为已接受的答案!
  • 不幸的是,我对这一切有点陌生,但我能够剖析您的答案并使其适用于我当前的设置。我会发布我所做的以使其适合我的问题。谢谢你,史蒂夫!
【解决方案2】:

将其作为数字存储/检索可能更容易。然后,您可以在查询时对其进行排序,并在显示时简单地转换回来。

DateTime.Ticks 会给你一个很长的纳秒数。

然后,您可以将其存储在数据库中,并在检索时将其转回 DateTime:

new DateTime(number)

这样就很容易对查询进行排序,因为“记号”数最多的就是最未来的日期时间。

【讨论】:

    猜你喜欢
    • 2014-11-18
    • 2017-07-11
    • 2013-01-26
    • 2022-08-17
    • 2016-07-18
    • 1970-01-01
    • 2015-11-02
    • 2012-02-12
    • 1970-01-01
    相关资源
    最近更新 更多