I have a large set of data with which server-side paging is implemented. I need to requery the data source any time the GridView's filter is changed by the user. The problem lies in the fact that rebinding the DataSource inside any of the FilterChanged, FilterChanging, or FilterExpressionChanged events of the grid causes a null reference exception at the application level.
To work around this, I have found the following code which will correctly refresh the data source after a filter change has been finalized.
While the data source now refreshed automatically on a text change, it still did not refresh on a filter type change (ie. "Contains" to "Does not contain"). I tried calling RequeryGridData() in the closed event of the filter popup menu as follows.
This still caused a null reference exception. I wondered what would happen if I delayed the datasource refresh until after the close event had finished and found myself with this code.
Which, as I suspected, works great. No exceptions occurred.
My question is: Is there a cleaner way of detecting the filter change and performing a datasource change? Perhaps this functionality is not the intended use of the GridView's filter controls, in which case I'll settle for the solution (read: hack) I've managed to come up with, but hopefully there is a better way to handle this.
Thank you for your time.
To work around this, I have found the following code which will correctly refresh the data source after a filter change has been finalized.
private
void
TicketView_CellEndEdit(
object
sender, GridViewCellEventArgs e)
{
if
((sender
as
GridViewEditManager).GridViewElement.CurrentCell
is
GridFilterCellElement)
{
RequeryGridData();
}
}
While the data source now refreshed automatically on a text change, it still did not refresh on a filter type change (ie. "Contains" to "Does not contain"). I tried calling RequeryGridData() in the closed event of the filter popup menu as follows.
private
void
TicketView_ContextMenuOpening(
object
sender, ContextMenuOpeningEventArgs e)
{
if
(e.ContextMenuProvider
is
GridFilterCellElement)
{
e.ContextMenu.DropDownClosed +=
new
RadPopupClosedEventHandler(FilterContextMenu_Closed);
}
}
void
FilterContextMenu_Closed(
object
sender, EventArgs e)
{
RequeryGridData();
}
This still caused a null reference exception. I wondered what would happen if I delayed the datasource refresh until after the close event had finished and found myself with this code.
private
void
TicketView_ContextMenuOpening(
object
sender, ContextMenuOpeningEventArgs e)
{
if
(e.ContextMenuProvider
is
GridFilterCellElement)
{
e.ContextMenu.DropDownClosed +=
new
RadPopupClosedEventHandler(FilterContextMenu_Closed);
}
}
void
FilterContextMenu_Closed(
object
sender, EventArgs e)
{
//HACK: Have to refresh grid contents, but MUST NOT do it from a filter changing event as
// updating the datasource while the filter change is finalized crashes the program
System.Windows.Forms.Timer timer =
new
System.Windows.Forms.Timer();
timer.Interval = 1;
timer.Tick +=
new
EventHandler(FilterChangedTimer_Tick);
timer.Start();
}
void
FilterChangedTimer_Tick(
object
sender, EventArgs e)
{
(sender
as
System.Windows.Forms.Timer).Dispose();
RequeryGridData();
}
Which, as I suspected, works great. No exceptions occurred.
My question is: Is there a cleaner way of detecting the filter change and performing a datasource change? Perhaps this functionality is not the intended use of the GridView's filter controls, in which case I'll settle for the solution (read: hack) I've managed to come up with, but hopefully there is a better way to handle this.
Thank you for your time.