Contents
At a glance
Installation and deployment
DNN
Licensing
Already using the control
Functional overview
ASP.NET 2.0 Features
Getting Started
Grid columns
Grid rows
Defining Structure
Visible/Enabled conventions
Populating the control with data
AJAX
Sorting
Paging
Scrolling
Grouping
Filtering
Selecting grid items
Insert/Update/Delete records
Hierarchical grid types and Load modes
Design-time support
Controlling visual appearance
Localization/Accessibility
RadGrid export
The control lifecycle
Performance tips and tricks
Telerik RadGrid inheritance
How-to
Troubleshooting
Integration with other controls
Client-side API Reference
API Reference
Need for help
|
|
| Filtering with MS DropDownList instead of textbox |
Send comments on this topic. |
|
|
Filtering > How to > Filtering with MS DropDownList instead of textbox |
In some cases you may whish to display the available options when the user choose an option from a dropdown list instead of textbox in grid column header. Then you may want choose an option and filter the record on item selection/Enter key press. This behavior is easily attainable by replacing the default textbox input with MS DropDownList instance. Here are the steps you need to undertake in order to configure the grid as mentioned above:
- extend the default GridBoundColumn to remove the default textbox and embed MS DropDownList inside the filtering cell
- configure the options for the dropdown list control as per your requirements (the essential parts are to set AutoPostBack = true, ID for the dropdown, binding the combobox items and wiring the SelectedIndexChanged event). These operation should take place in the overriden SetupFilterControls(TableCell cell) method
- override the SetCurrentFilterValueToControl(TableCell cell) / GetCurrentFilterValueFromControl(TableCell cell) methods to set/get the dropdown list SelectedValue.
- raise command event for the GridFilteringItem calling its FireCommandEvent(commandName, new Pair(filterFunctionName, columnUniqueName)) method
The example below is expanded by enabling the AJAX mechanism of the grid along with its built-in paging feature. The filtering action will be triggered when you choose item from the dropdown list filter or highlight list item and press Enter from the keyboard. In addition, there is Clear filter button on the page which restores the initial grid content.
 |
Note that when using data source controls (part of ASP.NET 2.0) the NeedDataSource event of the grid will not be fired. An online demo presenting similar approach with template column is available here. |
 |
The sample is enhanced with additional method which selects only distinct records for the dropdown list in the column header (useful when there are duplicate field values in the column source). Please note that we store the SelectedValue and the FilteredColumnName for the item clicked by the user in Session variables. Then we retrieve these values and filter the items in the dropdown filters (according to the current filter applied) inside the GetDropDownListItems method. | MainPage.aspx
| ASPX/ASCX |
Copy Code |
|
<rad:RadGrid ID="RadGrid1" Width="200px" AllowFilteringByColumn="True" AllowSorting="True" EnableAJAX="true" EnableAJAXLoadingTemplate="true" AllowPaging="True" runat="server" OnColumnCreating="RadGrid1_ColumnCreating" AutoGenerateColumns="False"> </rad:RadGrid> <asp:Button id="clrFilters" runat="server" Text="Clear filters" OnClick="clrFilters_Click" /> |
| C# |
Copy Code |
|
MainPage.cs
using System; using System.Data; using System.Collections; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; using Telerik.WebControls; using System.Data.OleDb;
public partial class TestFilter : System.Web.UI.Page { private DataSet ds; private DataSet dsTemp;
protected void Page_Load(object sender, EventArgs e) {
}
private void InitializeComponent() { this.RadGrid1.NeedDataSource += new Telerik.WebControls.GridNeedDataSourceEventHandler(this.RadGrid1_NeedDataSource); this.Load += new System.EventHandler(this.Page_Load); }
override protected void OnInit(EventArgs e) {
InitializeComponent(); base.OnInit(e); }
public DataTable SelectDistinct(string TableName, DataTable SourceTable, string FieldName) { DataTable dt = new DataTable(TableName); dt.Columns.Add(FieldName, SourceTable.Columns[FieldName].DataType);
object LastValue = null;
foreach (DataRow dr in SourceTable.Select("", FieldName)) { if (LastValue == null || !(ColumnEqual(LastValue, dr[FieldName]))) { LastValue = dr[FieldName]; dt.Rows.Add( new object[] { LastValue }); } } if (dsTemp != null) dsTemp.Tables.Add(dt); return dt; }
private bool ColumnEqual(object A, object B) {
// Compares two values to see if they are equal. Also compares DBNULL.Value. // Note: If your DataTable contains object fields, then you must extend this // function to handle them in a meaningful way if you intend to group on them.
if (A == DBNull.Value && B == DBNull.Value) // both are DBNull.Value return true; if (A == DBNull.Value || B == DBNull.Value) // only one is DBNull.Value return false; return (A.Equals(B)); // value type standard comparison }
private DataView GetDropDownListItems(DataSet SourceDS, string ColumnName, string pattern, string filteredColumnName) { DataSet dsColumn = new DataSet(ColumnName); dsColumn.Tables.Add(ColumnName); dsColumn.Tables[0].Columns.Add(ColumnName, SourceDS.Tables[0].Columns[ColumnName].DataType); foreach (DataRow row in SourceDS.Tables[0].Rows) { if (pattern == null) { dsColumn.Tables[0].Rows.Add(new object[] { row[ColumnName] }); } else if ((string)row[filteredColumnName] == pattern) { dsColumn.Tables[0].Rows.Add(new object[] { row[ColumnName] }); } } DataView dv = SelectDistinct(dsColumn.Tables[0].TableName, dsColumn.Tables[0], ColumnName).DefaultView; dv.Sort = ColumnName + " ASC"; return dv; }
protected void RadGrid1_NeedDataSource(object source, GridNeedDataSourceEventArgs e) { ds = DataSourceHelperCS.GetDataSet("SELECT ContactName, City, Country FROM Customers");
this.RadGrid1.MasterTableView.Columns.Clear();
foreach (DataColumn dataColumn in ds.Tables[0].Columns) { RadGrid.MyCustomFilteringColumn gridColumn = new RadGrid.MyCustomFilteringColumn(); this.RadGrid1.MasterTableView.Columns.Add(gridColumn);
gridColumn.DataField = dataColumn.ColumnName; gridColumn.HeaderText = dataColumn.ColumnName; gridColumn.ListDataSource = GetDropDownListItems(ds, dataColumn.ColumnName, (string)Session["SelectedValue"], (string)Session["FilteredColumnName"]); }
this.RadGrid1.DataSource = ds; }
protected void RadGrid1_ColumnCreating(object sender, GridColumnCreatingEventArgs e) { if (e.Column == null) { e.Column = new RadGrid.MyCustomFilteringColumn(); } } protected void clrFilters_Click(object sender, EventArgs e) { foreach (GridColumn column in RadGrid1.MasterTableView.Columns) { column.CurrentFilterFunction = GridKnownFunction.NoFilter; column.CurrentFilterValue = String.Empty; } Session["SelectedValue"] = null; Session["FilteredColumnName"] = null; RadGrid1.MasterTableView.FilterExpression = String.Empty; RadGrid1.MasterTableView.Rebind();
} } |
| C# |
Copy Code |
|
MyCustomFilteringColumn.cs
using System.Data; using Telerik.WebControls; using System.Web.UI.WebControls; using System.Web.UI; using System; using System.Collections;
namespace RadGrid { public class MyCustomFilteringColumn : GridBoundColumn { private object listDataSource = null;
//RadGrid will call this method when it initializes the controls inside the filtering item cells protected override void SetupFilterControls(TableCell cell) { base.SetupFilterControls(cell); cell.Controls.RemoveAt(0);
System.Web.UI.WebControls.DropDownList list = new System.Web.UI.WebControls.DropDownList(); list.ID = "list" + this.DataField;
list.Height = Unit.Pixel(300); list.AutoPostBack = true;
list.SelectedIndexChanged += new EventHandler(list_SelectedIndexChanged);
cell.Controls.AddAt(0, list); cell.Controls.RemoveAt(1);
list.DataTextField = this.DataField; list.DataValueField = this.DataField;
list.DataSource = this.ListDataSource; list.DataBind();
}
void list_SelectedIndexChanged(object sender, EventArgs e) { GridFilteringItem filterItem = (sender as DropDownList).NamingContainer as GridFilteringItem;
this.SelectedValue = (sender as DropDownList).SelectedValue; this.FilteredColumnName = this.UniqueName;
if (this.UniqueName == "Index") { //this is example for filtering for integer column type filterItem.FireCommandEvent( "Filter", new Pair("EqualTo", this.UniqueName)); } //filtering for string column type filterItem.FireCommandEvent( "Filter", new Pair("Contains", this.UniqueName));
} public object ListDataSource { get { return this.listDataSource; } set { listDataSource = value; } } public string SelectedValue { get { object res = this.Owner.OwnerGrid.Page.Session["SelectedValue"]; if (res != null) { return (string)res; } return ""; } set { this.Owner.OwnerGrid.Page.Session[ "SelectedValue"] = value; } } public string FilteredColumnName { get { object res = this.Owner.OwnerGrid.Page.Session["FilteredColumnName"]; if (res != null) { return (string)res; } return ""; } set { this.Owner.OwnerGrid.Page.Session["FilteredColumnName"] = value; } } //RadGrid will call this method when the value should be set to the filtering input control(s) protected override void SetCurrentFilterValueToControl(TableCell cell) { base.SetCurrentFilterValueToControl(cell);
System.Web.UI.WebControls.DropDownList list = (System.Web.UI.WebControls.DropDownList)cell.Controls[0]; if (this.CurrentFilterValue != string.Empty) { list.SelectedValue = this.CurrentFilterValue; } }
//RadGrid will call this method when the filtering value should be extracted from the filtering input control(s) protected override string GetCurrentFilterValueFromControl(TableCell cell) { System.Web.UI.WebControls.DropDownList list = (System.Web.UI.WebControls.DropDownList)cell.Controls[0];
return list.SelectedValue; } public override GridColumn Clone() { return base.Clone(); } protected override string GetFilterDataField() { return this.DataField; }
} } |
| VB.NET |
Copy Code |
|
MainPage.vb
Imports Telerik.WebControls Imports System.Data.OleDb Imports System.Data Imports System.Collections Imports System.Web Imports System.Web.UI Imports System.Web.UI.WebControls Imports System.Web.UI.HtmlControls
Partial Class _TestFilter Inherits System.Web.UI.Page
Dim ds As DataSet Dim dsTemp As DataSet Public Function SelectDistinct(ByVal TableName As String, ByVal SourceTable As DataTable, ByVal FieldName As String) As DataTable Dim dt As New DataTable(TableName) dt.Columns.Add(FieldName, SourceTable.Columns(FieldName).DataType)
Dim LastValue As Object = Nothing
Dim dr As DataRow For Each dr In SourceTable.Select("", FieldName) If LastValue Is Nothing Or Not ColumnEqual(LastValue, dr(FieldName)) Then LastValue = dr(FieldName) dt.Rows.Add( New Object() {LastValue}) End If Next dr If Not (dsTemp Is Nothing) Then dsTemp.Tables.Add(dt) End If Return dt End Function
Private Function ColumnEqual(ByVal A As Object, ByVal B As Object) As Boolean
If A Is DBNull.Value And B Is DBNull.Value Then Return True End If If A Is DBNull.Value Or B Is DBNull.Value Then Return False End If Return A.Equals(B) End Function
Private Function GetDropDownListItems(ByVal SourceDS As DataSet, ByVal ColumnName As String, ByVal pattern As String, ByVal filteredColumnName As String) As DataView Dim dsColumn As New DataSet(ColumnName)
dsColumn.Tables.Add(ColumnName)
dsColumn.Tables(0).Columns.Add(ColumnName, SourceDS.Tables(0).Columns(ColumnName).DataType)
Dim row As DataRow For Each row In SourceDS.Tables(0).Rows If pattern Is Nothing Then dsColumn.Tables(0).Rows.Add( New Object() {row(ColumnName)}) ElseIf CStr(row(filteredColumnName)) = pattern Then dsColumn.Tables(0).Rows.Add( New Object() {row(ColumnName)}) End If Next row
Dim dv As DataView = SelectDistinct(dsColumn.Tables(0).TableName, dsColumn.Tables(0), ColumnName).DefaultView dv.Sort = ColumnName + " ASC"
Return dv End Function
Protected Sub RadGrid1_NeedDataSource(ByVal source As Object, ByVal e As Telerik.WebControls.GridNeedDataSourceEventArgs) Handles RadGrid1.NeedDataSource ds = DataSourceHelperVB.GetDataSet("SELECT ContactName, City, Country FROM Customers") Me.RadGrid1.MasterTableView.Columns.Clear()
Dim dataColumn As DataColumn For Each dataColumn In ds.Tables(0).Columns Dim gridColumn As New RadGrid.MyCustomFilteringColumn() Me.RadGrid1.MasterTableView.Columns.Add(gridColumn)
gridColumn.DataField = dataColumn.ColumnName gridColumn.HeaderText = dataColumn.ColumnName gridColumn.ListDataSource = GetDropDownListItems(ds, dataColumn.ColumnName, CStr(Session("SelectedValue")), CStr(Session("FilteredColumnName"))) Next dataColumn
Me.RadGrid1.DataSource = ds End Sub
Protected Sub RadGrid1_ColumnCreating(ByVal sender As Object, ByVal e As Telerik.WebControls.GridColumnCreatingEventArgs) Handles RadGrid1.ColumnCreating If e.Column Is Nothing Then e.Column = New RadGrid.MyCustomFilteringColumn() End If End Sub
Protected Sub clrFilters_Click(ByVal sender As Object, ByVal e As EventArgs) Dim column As GridColumn For Each column In RadGrid1.MasterTableView.Columns column.CurrentFilterFunction = GridKnownFunction.NoFilter column.CurrentFilterValue = [String].Empty Next column Session( "SelectedValue") = Nothing Session( "FilteredColumnName") = Nothing
RadGrid1.MasterTableView.FilterExpression = [String].Empty RadGrid1.MasterTableView.Rebind() End Sub End Class |
| VB.NET |
Copy Code |
|
MyCustomFilteringColumn.vb
Imports Microsoft.VisualBasic Imports System.Data Imports Telerik.WebControls Imports System.Web.UI.WebControls Imports System.Web.UI Imports System Imports System.Collections
Namespace RadGrid
Public Class MyCustomFilteringColumn Inherits GridBoundColumn
Private lDataSource As Object = Nothing
Protected Overrides Sub SetupFilterControls(ByVal cell As TableCell) MyBase.SetupFilterControls(cell) cell.Controls.RemoveAt(0)
Dim list As New System.Web.UI.WebControls.DropDownList() list.ID = "list" + Me.DataField
list.Height = Unit.Pixel(300) list.AutoPostBack = True
AddHandler list.SelectedIndexChanged, AddressOf list_SelectedIndexChanged
cell.Controls.AddAt(0, list) cell.Controls.RemoveAt(1)
list.DataTextField = Me.DataField list.DataValueField = Me.DataField
list.DataSource = Me.listDataSource list.DataBind() End Sub
Sub list_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs) Dim ddl As DropDownList = CType(sender, DropDownList) Dim filterItem As GridFilteringItem = CType(ddl.NamingContainer, GridFilteringItem)
Me.SelectedValue = CType(sender, DropDownList).SelectedValue Me.FilteredColumnName = Me.UniqueName
If Me.UniqueName = "Index" Then filterItem.FireCommandEvent( "Filter", New Pair("EqualTo", Me.UniqueName)) End If filterItem.FireCommandEvent( "Filter", New Pair("Contains", Me.UniqueName)) End Sub
Public Property ListDataSource() As Object Get Return Me.lDataSource End Get Set(ByVal value As Object) lDataSource = value End Set End Property
Public Property SelectedValue() As String Get Dim res As Object = Me.Owner.OwnerGrid.Page.Session( "SelectedValue") If Not (res Is Nothing) Then Return CStr(res) End If Return "" End Get Set(ByVal value As String) Me.Owner.OwnerGrid.Page.Session( "SelectedValue") = value End Set End Property
Public Property FilteredColumnName() As String Get Dim res As Object = Me.Owner.OwnerGrid.Page.Session( "FilteredColumnName") If Not (res Is Nothing) Then Return CStr(res) End If Return "" End Get Set(ByVal value As String) Me.Owner.OwnerGrid.Page.Session( "FilteredColumnName") = value End Set End Property
Protected Overrides Sub SetCurrentFilterValueToControl(ByVal cell As TableCell) MyBase.SetCurrentFilterValueToControl(cell)
Dim list As System.Web.UI.WebControls.DropDownList = CType(cell.Controls(0), System.Web.UI.WebControls.DropDownList) If Me.CurrentFilterValue <> String.Empty Then list.SelectedValue = Me.CurrentFilterValue End If End Sub
Protected Overrides Function GetCurrentFilterValueFromControl(ByVal cell As TableCell) As String Dim list As System.Web.UI.WebControls.DropDownList = CType(cell.Controls(0), System.Web.UI.WebControls.DropDownList)
Return list.SelectedValue End Function
Public Overrides Function Clone() As GridColumn Return MyBase.Clone() End Function
Protected Overrides Function GetFilterDataField() As String Return Me.DataField End Function
End Class
End Namespace |
|