Reputation: 1539
I'm trying to filter a deadline column in a datagridview by 2 datetimepickers - startDate and endDate.
datagridview is TaskTable2, datetimepicker1 is startSchedule, datetimepicker2 is endSchedule and deadline in datagridview is deadlineRow
So far I have got the following code which is successfully making the rows invisible which are not between the selected start and end date.
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.
}
}
However, I have a few existing problems:
'Row associated with the currency manager's position cannot be made invisible'
The datagridview is bound to an XML file so data can be removed from the datagridview for filtering and printing aslong as they remain in the XML file.
Any help would be greatly appreciated!
Thankyou
Upvotes: 4
Views: 7352
Reputation: 4720
I faced exact same problem with exception 'Row associated with the currency manager's position cannot be made invisible'.
dgridView.CurrentCell = null;
dgridView.Rows[i].Visible = false;
Just setting the CurrentCell to null fixed it for me. I haven't checked it further, if it breaks something.
Upvotes: 1
Reputation: 4330
Found a solution to the exception here: http://discuss.itacumens.com/index.php?topic=16375.0
I added this to my code directly before I attempt to set the row to be not visible. row
is my ForEach
loop variable. I check to see if its selected and if it is attempt to clear the row and cell selection before setting the visible
property.
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
It seems the issue is with making the current row or cell not visible.
Upvotes: 2
Reputation: 247700
I would use the Filter
property on the bindingsource
for the datagridview
. The Filter
property allows you to view a subset of the DataSource.
Example from 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&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'";
}
I use this type of Filter
to show data based on account. For an account, I have a textbox when the user places the account number and I use the TextChanged
Event to apply the filter. Then I have a button that is used to remove the Filter from the binding source.
If you want to filter by date you can following instructions in this SO question:
Using the filter on a date that is not present should not crash the app, it will just display nothing.
Upvotes: 4