使用日期对数据网格进行过滤

4
我正在尝试通过两个日期选择器startDate和endDate筛选datagridview中的deadline列。
datagridview是TaskTable2, datetimepicker1是startSchedule, datetimepicker2是endSchedule, datagridview中的deadline是deadlineRow。
到目前为止,我已经得到了以下代码,成功地使不在所选起始日期和结束日期之间的行变得不可见。
private void scheduleButton_Click(object sender, EventArgs e)
    {

        DateTime startSchedule = startDate.Value.Date;
        DateTime endSchedule = endDate.Value.Date;

        if (startSchedule <= endSchedule)// runs foreach loop if startdate and enddate are valid
        {
            foreach (DataGridViewRow dr in TaskTable2.Rows)// loops through rows of datagridview
            {
                string deadline = dr.Cells["Deadline"].Value.ToString(); // gets deadline values
                DateTime deadlineRow = Convert.ToDateTime(deadline); // converts deadline string to datetime and stores in deadlineRow variable

                if (startSchedule <= deadlineRow && deadlineRow <= endSchedule) // filters deadlines that are => startDate and <= endDate
                {
                    dr.Visible = true; // display filtered rows here.
                }
                else
                {
                    dr.Visible = false; // hide rows that are not beteen start and end date.
                }

            }
        }
        else
        {     
            MessageBox.Show("Please ensure Start Date is set before End Date."); // ensures user selects an end date after the start date.
        }
    }

然而,我遇到了几个问题:
  1. 当我选择一个日期范围来显示没有任务时,应用程序会崩溃并出现以下错误:

'Row associated with the currency manager's position cannot be made invisible'

  1. 我有一个打印按钮,它应该打印过滤后的结果。 然而,它打印出了 datagridview 中存储的所有数据,即使某些行的 visible=false 从按计划按钮,所以我猜我需要使用不同的方法来删除行,而不是隐藏它们。

datagridview 绑定到一个 XML 文件,因此可以从 datagridview 中删除数据以进行筛选和打印,只要它们仍然在 XML 文件中。

非常感谢您的帮助!

谢谢

3个回答

4
我会在bindingsource上使用Filter属性来对datagridview进行筛选。Filter属性允许您查看数据源的子集。
来自MSDN的示例:
private void PopulateDataViewAndFilter()
{
    DataSet set1 = new DataSet();

    // Some xml data to populate the DataSet with.
    string musicXml =
        "<?xml version='1.0' encoding='UTF-8'?>" +
        "<music>" +
        "<recording><artist>Coldplay</artist><cd>X&amp;Y</cd></recording>" +
        "<recording><artist>Dave Matthews</artist><cd>Under the Table and Dreaming</cd></recording>" +
        "<recording><artist>Dave Matthews</artist><cd>Live at Red Rocks</cd></recording>" +
        "<recording><artist>Natalie Merchant</artist><cd>Tigerlily</cd></recording>" +
        "<recording><artist>U2</artist><cd>How to Dismantle an Atomic Bomb</cd></recording>" +
        "</music>";

    // Read the xml.
    StringReader reader = new StringReader(musicXml);
    set1.ReadXml(reader);

    // Get a DataView of the table contained in the dataset.
    DataTableCollection tables = set1.Tables;
    DataView view1 = new DataView(tables[0]);

    // Create a DataGridView control and add it to the form.
    DataGridView datagridview1 = new DataGridView();
    datagridview1.AutoGenerateColumns = true;
    this.Controls.Add(datagridview1);

    // Create a BindingSource and set its DataSource property to
    // the DataView.
    BindingSource source1 = new BindingSource();
    source1.DataSource = view1;

    // Set the data source for the DataGridView.
    datagridview1.DataSource = source1;

    //The Filter string can include Boolean expressions.
    source1.Filter = "artist = 'Dave Matthews' OR cd = 'Tigerlily'";
}

我使用这种类型的 Filter 来根据账户显示数据。对于一个账户,我有一个文本框让用户输入账户号码,我使用 TextChanged 事件来应用过滤器。然后我有一个按钮用于从绑定源中删除过滤器。
如果您想按日期筛选,请按照此 SO 问题中的说明操作: BindingSource Filter by date 在不存在的日期上使用过滤器不会导致应用程序崩溃,只会显示空白。

2
在这里找到了解决异常的方法: http://discuss.itacumens.com/index.php?topic=16375.0 在我尝试将行设置为不可见之前,我直接将此代码添加到我的代码中。 row 是我的 ForEach 循环变量。我检查它是否被选中,如果是,则尝试清除行和单元格选择,然后设置 visible 属性。
            If gridItems.SelectedRows.Count > 0 AndAlso row.Index = gridItems.SelectedRows(0).Index Then
                'fixes dumb exception with row.visible = false 
                gridItems.ClearSelection()
                gridItems.CurrentCell = Nothing
            End If

看起来问题出在使当前行或单元格不可见上。


好像你甚至不需要先清除选择;将CurrentCell设置为null/nothing就可以了。谢谢你的提示! - Nick Spreitzer

1

我遇到了与异常“无法使与货币管理器位置相关联的行不可见”完全相同的问题。

dgridView.CurrentCell = null;
dgridView.Rows[i].Visible = false;

只需将CurrentCell设置为null,问题就解决了。我还没有进一步检查它是否会影响其他功能。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接