Tweaking the Filter Repeater


The default implementation of Dynamic Data provides a drop down list box for each foreign key and boolean field in a table. The drop down list allows you to filter the table with the value selected from the drop down list box. The figure below shows a view of the Product table from the AdventureWorksLT database. Several columns are not displayed because the scaffoldcolumnattribute was applied.


The figure below shows the Product table again after Mountain Bikes is selected in the ProductCategory drop down list. Only products with product category Mountain Bikes are displayed.


The drop down list box is implemented in Dynamic Data by the FilterUserControl.ascx user control in the DynamicData\Content folder. While the filter user control is useful to filter a table when there are a relatively few foreign keys used as categories, it can be unmanageable on tables with hundreds or more foreign keys. For example, the CustomerAddress table of the AdventureWorksLT database has over 400 AddressID foreign keys, and each foreign key points to only one address of a customer (either the Main Office or the Shipping address).

When the foreign key field displayed by the filter user control is a very long string, the drop down list box can move off the browser window. This document will offer and approach to limit the width of the drop down list box. The figure below shows the ProductModelProductDescriptions from the AdventureWorksLT database.

In this blog I show how I like to establish a maximum number of entries in the filter repeater and how to set the maximum width.


Modifying the filter user control to limit number of entries


Editing the filter user control

1. Add a key element to the appSettings Element in the web.config file that will set an upper bound to the number of foreign key entries that will be displayed. The following example sets the upper bound to 55. 

<appSettings>
<
add key=FilterUC_FK_limitvalue=955/>
<
add key=FilterUC_Char_limitvalue=50/>
</
appSettings>

1 Add a text label to the the filter user control in the FilterUserControl.ascx file found in the DynamicData\Content folder. The following example shows the completed markup.

<%@ Control Language=”C#” CodeFile=”FilterUserControl.ascx.cs” Inherits=”FilterUserControl” %>

<asp:Label ID=”LBL1″ runat=”server” Text=”Label” ForeColor= “Brown” Font-Bold=”true” />
<
asp:DropDownList ID=”DropDownList1″ runat=”server” AutoPostBack=”true” EnableViewState=”true” CssClass=”droplist”>
<
asp:ListItem Text=”All” Value=”” />
</
asp:DropDownList>


3. Add a string property to the FilterUserControl. For example, add a property with the name LBL_Txt that will be used to set the label we added to the FilterUserControl.aspx file in a previous step.

4. Add the Page_PreRender method in the FilterUserControl code behind file and set the label text. For example, set the label text with the LBL_Txt property created in the previous step.

5. Modify the Page_Init method in the FilterUserControl code behind file to limit the number of foreign keys displayed. The FilterUC_FK_limit application setting created in the first step will be used to set the maximum number of entries in the drop down list box. The following example shows the completed FilterUserControl code behind file.

Visual Basic

Imports System.Web.DynamicData

Partial Class FilterUserControl
Inherits System.Web.DynamicData.FilterUserControlBase

Public LBL_Txt As String

Public Overrides ReadOnly Property SelectedValue As String
Get
Return
DropDownList1.SelectedValue
End Get
End Property

Public Event SelectedIndexChanged As EventHandler

Protected Sub Page_Init(ByVal sender As Object, ByVal e As EventArgs)

If Page.IsPostBack Then
Return
End If

PopulateListControl(DropDownList1)

Dim maxCnt As Integer = Convert.ToInt32(ConfigurationManager.AppSettings(“FilterUC_FK_limit”))
If (DropDownList1.Items.Count > maxCnt) Then
DropDownList1.Visible = False
LBL1.Visible = False
End If

If Not String.IsNullOrEmpty(InitialValue) Then
DropDownList1.SelectedValue = InitialValue
End If

End Sub


Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreRender
LBL1.Text = LBL_Txt
End Sub
End Class


C#

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Collections.Specialized;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml.Linq;
using System.Web.DynamicData;

public partial class FilterUserControl : System.Web.DynamicData.FilterUserControlBase {

public string LBL_Txt { get; set; }

public event EventHandler SelectedIndexChanged {
add {
DropDownList1.SelectedIndexChanged += value;
}
remove {
DropDownList1.SelectedIndexChanged -= value;
}
}

public override string SelectedValue {
get {
return DropDownList1.SelectedValue;
}
}

protected void Page_PreRender(object sender, EventArgs e) {
LBL1.Text = LBL_Txt;
}

protected void Page_Init(object sender, EventArgs e) {

if (Page.IsPostBack)
return; PopulateListControl(DropDownList1);

int maxCnt = Convert.ToInt32(ConfigurationManager.AppSettings[“FilterUC_FK_limit”]);
if (DropDownList1.Items.Count > maxCnt) {
DropDownList1.Visible = false;
LBL1.Visible = false;
}

if (!String.IsNullOrEmpty(InitialValue))
DropDownList1.SelectedValue = InitialValue;
}
}



 


5. Remove the original filter label from the page template (list.aspx and listDetails.aspx) and initialize the new label. The original markup is shown below.

<asp:FilterRepeater ID=”FilterRepeater” runat=”server”>
<
ItemTemplate>
<
asp:Label runat=”server” Text=’<%# Eval(“DisplayName”) %>AssociatedControlID=”DynamicFilter$DropDownList1″ />
<
asp:DynamicFilter runat=”server” ID=”DynamicFilter” OnSelectedIndexChanged=”OnFilterSelectedIndexChanged” />
</
ItemTemplate>
<
FooterTemplate><br /><br /></FooterTemplate>
</
asp:FilterRepeater>

The replacement markup is shown below.

<ItemTemplate>
<
asp:DynamicFilter runat=”server” ID=”DynamicFilter” LBL_Txt=’<%# Eval(“DisplayName”) %>
OnSelectedIndexChanged=”OnFilterSelectedIndexChanged” />
</
ItemTemplate>

 


Part II:  Limiting the width of the filter user control Part II:

To limit the width of the drop down list box, the elements of the list box will be truncated at the maximum allowed character width.Editing the filter user control for maximum characters1. Add a key element to the appSettings Element in the web.config file that will set an upper bound on the number of characters that will be copied to each element of the drop downn list. The key with value FilterUC_Char_limit sets the maximum number of characters to 50.

<appSettings>
<
add key=FilterUC_FK_limitvalue=955/>
<
add key=FilterUC_Char_limitvalue=50/>
</
appSettings>

2. Modify the Page_Init method in the FilterUserControl code behind file to limit the number of characters to be copied to the drop down list box. The following example shows how to limit the number of characters.

C#

int maxLen = Convert.ToInt32(ConfigurationManager.AppSettings[“FilterUC_Char_limit”]);

for (int i = 0; i < DropDownList1.Items.Count; i++) {
string s = DropDownList1.Items[i].Text;

if (s.Length > maxLen) {
s = s.Substring(0, maxLen – 1);
s += ” … (see Details for full)”;
DropDownList1.Items[i].Text = s;
}
}


Visual Basic

Dim maxLen As Integer = Convert.ToInt32(ConfigurationManager.AppSettings(“FilterUC_Char_limit”))
For i As Integer = 0 To DropDownList1.Items.Count – 1

Dim s As String = DropDownList1.Items(i).Text

If s.Length > maxLen Then
s = s.Substring(0, maxLen – 1)
s += ” … (see Details for full)”
DropDownList1.Items(i).Text = s
End If
Next


The figure below shows the results with the ProductModelProductDescription table.

Comments (4)

  1. You’ve been kicked (a good thing) – Trackback from DotNetKicks.com

  2. wisemx says:

    Very cool…Thanks for laying it out so nicely.

  3. Please post corrections/new submissions to the Dynamic Data Forum . Put FAQ Submission/Correction in

  4. Mike says:

    Could this sample be updated for .NET 4?