【问题标题】:Filtering a datagridview using dates使用日期过滤数据网格视图
【发布时间】:2012-03-29 21:43:03
【问题描述】:

我正在尝试通过 2 个日期时间选择器(startDate 和 endDate)过滤 datagridview 中的截止日期列。

datagridview 是TaskTable2, datetimepicker1 是 startSchedule, datetimepicker2 是 endSchedule 和 datagridview 中的截止日期是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. 当我选择不显示任何任务的日期范围时,应用程序崩溃并出现以下错误:

'不能使与货币经理职位相关的行不可见'

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

datagridview 绑定到一个 XML 文件,因此只要数据保留在 XML 文件中,就可以从 datagridview 中删除数据以进行过滤和打印。

任何帮助将不胜感激!

谢谢

【问题讨论】:

    标签: c# winforms datagridview datetimepicker


    【解决方案1】:

    我遇到了完全相同的问题,例外是“不能使与货币经理职位相关的行不可见”。

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

    只需将 CurrentCell 设置为 null 即可为我修复它。我还没有进一步检查它,如果它破坏了什么。

    【讨论】:

      【解决方案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 对我有用。感谢您的提示!
      【解决方案3】:

      我会将bindingsource 上的Filter 属性用于datagridviewFilter 属性允许您查看数据源的子集。

      来自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

      在不存在的日期使用过滤器不会使应用程序崩溃,它不会显示任何内容。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-04-17
        • 1970-01-01
        • 2012-11-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多