简体   繁体   English

将DataGrid列排序为日期

[英]Sorting DataGrid Column as Date

I have a program I'm writing to help my company keep track of tool calibration. 我有一个正在编写的程序可以帮助我的公司跟踪工具校准。 I have all of the tools saved in a SQLite database, which does not have the option to set a column type to DATETIME. 我将所有工具都保存在SQLite数据库中,该数据库没有将列类型设置为DATETIME的选项。 So I've stored the dates in a M/D/YYYY format to keep it simple. 因此,为了简化起见,我将日期存储为M / D / YYYY格式。

I have the model pull the tool inventory from the database and return the populated table to the viewmodel. 我有模型从数据库中提取工具清单,然后将填充的表返回到viewmodel。

From here I've bound the viewmodel data table to the data grid, also binding each of the data grid columns to the appropriate columns in the data table. 从这里开始,我将viewmodel数据表绑定到数据网格,还将每个数据网格列绑定到数据表中的相应列。

I want the user to be able to sort the "calibration due" column from newest to oldest or oldest to newest. 我希望用户能够将“到期校准”列从最新到最旧或从最旧到最新进行排序。

The problem is that since both SQLite and the DataGrid control don't seem to have options for DateTime columns, the datagrid continues to sort these as strings. 问题在于,由于SQLite和DataGrid控件似乎都没有DateTime列的选项,因此datagrid继续将它们作为字符串排序。

The DataGrid columns are set as DataGridTextColumns since I couldn't find out if a templated column would fix this, or even how to use one. DataGrid列设置为DataGridTextColumns,因为我无法确定模板化的列是否可以解决此问题,甚至无法解决该问题。

I.E. :

9/26/2017

9/12/2017

8/5/2017

8/28/2017

I've tried converting the dates to a MM/DD/YYYY format, but that didn't work. 我试过将日期转换为MM / DD / YYYY格式,但这没有用。 Could anyone help me figure out what I need to do to get the proper sorting for these dates? 有人可以帮我弄清楚我需要怎么做才能对这些日期进行正确的排序吗?

I'm using Caliburn.Micro and SQLite if that helps narrow down the possible solutions. 我正在使用Caliburn.Micro和SQLite,这有助于缩小可能的解决方案的范围。

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

Thank you! 谢谢!

THE SOLUTION 解决方案

I transferred the data from the data table I filled to a list and returned the list. 我将数据从填充的数据表转移到列表中,然后返回列表。

CheckOutInViewModel: CheckOutInViewModel:

    private List<RosterData> _toolRoster;

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

CheckOutInModel: 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;
        }
    }

RosterData.cs: RosterData.cs:

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

Just define your custom class instead of loading a datatable. 只需定义您的自定义类即可,而不是加载数据表。 Use an SQLiteDateReader and convert each record to an element of a List of your custom class 使用SQLiteDateReader并将每条记录转换为自定义类的List的元素

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);
    }
}

It may be easier to store/retrieve it as a number. 以数字形式存储/检索可能会更容易。 You can then sort it when you query it and simply convert back at display time. 然后,您可以在查询时对其进行排序,并在显示时简单地转换回来。

DateTime.Ticks will give you a long which is the number of nanoseconds. DateTime.Ticks将为您提供很长的时间(纳秒数)。

You can then store that in the DB and turn it back into a DateTime on retrieval with: 然后可以将其存储在数据库中,并通过以下方式将其转换为DateTime:

new DateTime(number)

Sorting on query is then easy, as whichever has the highest number of "ticks" is the most future DateTime. 这样,对查询进行排序就很容易了,因为“打勾”次数最多的那个就是将来的DateTime。

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

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