פילטור ב - RadGrid בעזרת CmoboBox
לא מזמן קנינו את החבילה של
Telerik ל -
Web, אני חושב שזה בחירה נבונה לעבוד עם הפקדים שלהם.
בכל מקרה רציתי להדגים כאן, איך ניתן לייצר גריד שיש לו את האפשרות לפלטר בעזרת ComboBox שנותן לבחור מתוך הערכים.
לגריד של telerik יש מנגנון פילטרניג מובנה - אבל אין את האפשרות ל - Combo.
כדי שיהיה לנו Combo צריך לעשות את הדבר הבא.
כתבתי מחלקה כללית שתשמש אותי בכל הפרוייקטים שאני עובד עם Telerik.
אנחנו צריכים לרשת מהמחלקה GridTemplateColumn ולדרוס את המתודות הבאות
SetupFilterControls
SetCurrentFilterValueToControl
GetCurrentFilterValueFromControl
SupportsFiltering
ConvertValueIfEmpty
והנה המימוש
public class DDLFilterColumn : GridTemplateColumn
{
המתודה הראשונה
protected override void SetupFilterControls(TableCell cell)
{
RadComboBox rcBox = InitProperties();
cell.Controls.Add(rcBox);
if (!DesignMode)
{
FireFillingItems(this, new DDLFilterItemsEventArgs(rcBox));
}
}
מייצרים RadComboBox מוסיפים אותו לתא (שקבלנו) במידה ואנחנו בזמן ריצה נפעיל אירוע (שלנו - עוד מעט נראה אותו) שימלא אותו בערכים.
כדי לייצר את ה - RadCombo הפעלנו את המתודה הבאה
private RadComboBox InitProperties()
{
RadComboBox rcBox = new RadComboBox();
rcBox.ID = ("DropDownList1" + this.UniqueName);
rcBox.SelectedIndexChanged += rcBox_SelectedIndexChanged;
rcBox.Width = this.FilterControlWidth;
rcBox.AutoPostBack = true;
rcBox.DataTextField = this.DataField;
rcBox.DataValueField = this.DataField;
return rcBox;
}
מייצר את ה - Combo ונרשם לאירוע של SelectedIndexChanged שבו אנחנו נספר לגריד שאנחנו רוצים לפלטר
void rcBox_SelectedIndexChanged(object sender, RadComboBoxSelectedIndexChangedEventArgs e)
{
GridFilteringItem filteringItem = (GridFilteringItem)(((RadComboBox)sender).Parent.Parent);
filteringItem.FireCommandEvent("Filter", new Pair());
}
נחזור למתודה הראשונה, ראינו את הקוד הבא
if (!DesignMode)
{
FireFillingItems(this, new DDLFilterItemsEventArgs(rcBox));
}
כדי שהמחלקה תהיה כללית - כתבתי את הקוד הבא (מחוץ למחלקה של DDLFilterColumn)
public delegate void DDLFilterItemsEventHandler(object sender, DDLFilterItemsEventArgs args);
public class DDLFilterItemsEventArgs : EventArgs
{
public RadComboBox ComboBox { get; private set; }
public DDLFilterItemsEventArgs(RadComboBox comboBox)
{
ComboBox = comboBox;
}
}
ובמחלקה שלנו הוספתי אירוע מהסוג של ה - delegate
public event DDLFilterItemsEventHandler FillingItems;
protected virtual void FireFillingItems(object sender, DDLFilterItemsEventArgs args)
{
if (FillingItems != null)
{
FillingItems(sender, args);
}
}
במידה ונרשמו לאירוע (מה - aspx) האירוע יופעל מיד אחרי יצירת ה - Combo.
נעבור למתודות הבאות.
עד עכשיו ראינו את המתודה שיוצרת את ה - Combo, כמו שכתבתי אנחנו גם צריכים להגדיר איך מוצאים את הערך עבור ה - Filter ואיך מכניסים פנימה
protected override void SetCurrentFilterValueToControl(TableCell cell)
{
if (this.CurrentFilterValue != string.Empty)
{
var rcmi = ((RadComboBox)cell.Controls[0]).Items.FindItemByText(this.CurrentFilterValue);
if (rcmi != null)
{
rcmi.Selected = true;
}
}
}
protected override string GetCurrentFilterValueFromControl(TableCell cell)
{
string currentValue = ((RadComboBox)cell.Controls[0]).SelectedItem.Text;
CurrentFilterFunction = (currentValue != string.Empty) ?
GridKnownFunction.EqualTo :
GridKnownFunction.NoFilter;
return currentValue;
}
כמובן שצריך להוסיף את הקוד הבא:
public override bool SupportsFiltering()
{
return true;
}
ומומלץ לכתוב גם את זה (כדי שהגריד ירנדר רווח עבור שורות שאין בהם טקסט - אחרת הוא גם לא יידע לרנדר את ה - border)
protected override object ConvertValueIfEmpty(string value)
{
if (value == null || value.ToString() == string.Empty)
{
return " ";
}
return value.ToString();
}
כעת נראה את הדף
<telerik:RadGrid ID="RadGrid1" runat="server" OnNeedDataSource="RadGrid1_NeedDataSource"
AllowFilteringByColumn="true" AutoGenerateColumns="false">
<MasterTableView>
<Columns>
<telerik:DDLFilterColumn DataField="a" HeaderText="a" UniqueName="a"
OnFillingItems="a_DDLFiltering">
<ItemTemplate>
<asp:Label ID="lbl1" runat="server" Text='<%# Eval("a") %>'></asp:Label>
</ItemTemplate>
</telerik:DDLFilterColumn>
<telerik:DDLFilterColumn DataField="b" HeaderText="b" UniqueName="b"
OnFillingItems="a_DDLFiltering">
<ItemTemplate>
<asp:Label ID="lbl2" runat="server" Text='<%# Eval("b") %>'></asp:Label>
</ItemTemplate>
</telerik:DDLFilterColumn>
<telerik:DDLFilterColumn DataField="c" HeaderText="c" UniqueName="c"
OnFillingItems="a_DDLFiltering">
<ItemTemplate>
<asp:Label ID="lbl3" runat="server" Text='<%# Eval("c") %>'></asp:Label>
</ItemTemplate>
</telerik:DDLFilterColumn>
</Columns>
</MasterTableView>
</telerik:RadGrid>
מה שחשוב זה להגדיר את ה - DataField ואת ה - UniqeName כמו כן הגדרתי את המתודה למילוי ה - Combo (במקרה הזה מדובר באותה מתודה לכל ה - Combos)
צריך כמובן לזכור להוסיף את השורה הבאה
<%@ Register Assembly="WebApplication1" Namespace="Custom" TagPrefix="telerik" %>
קוד צד שרת:
המתודה שמביאה נתונים לגריד
protected void RadGrid1_NeedDataSource(object source, Telerik.Web.UI.GridNeedDataSourceEventArgs e)
{
DataTable table = (DataTable)Session["table"];
if (table == null)
{
table = CreateTable();
Session["table"] = table;
}
RadGrid1.DataSource = table;
}
private static DataTable CreateTable()
{
DataTable table = new DataTable();
table.Columns.Add("a");
table.Columns.Add("b");
table.Columns.Add("c");
table.Rows.Add("Day", "Private", "a");
table.Rows.Add("Day", "Private", "b");
table.Rows.Add("Day", "Public", "c");
table.Rows.Add("Day", "Public", "d");
table.Rows.Add("Evening", "Certificate", "e");
table.Rows.Add("Evening", "Certificate", "f");
table.Rows.Add("Evening", "Certificate", "g");
return table;
}
אני בודק האם יש ב - Session טבלה, אם לא אני מייצר אחד כזה ומקשר את הגריד לטבלה.
וכמובן המתודה שממלאה את ה - Combo בערכים
protected void a_DDLFiltering(object sender, DDLFilterItemsEventArgs args)
{
args.ComboBox.Items.Clear();
List<string> list = new List<string>();
DataTable table = (DataTable)Session["table"];
for (int i = 0; i < table.Rows.Count; i++)
{
string text = table.Rows[i][args.ComboBox.DataValueField].ToString();
if (!list.Contains(text))
{
list.Add(text);
}
}
list.Sort();
args.ComboBox.Items.AddRange(list.ConvertAll<RadComboBoxItem>(x => new RadComboBoxItem(x)));
args.ComboBox.Items.Insert(0, new RadComboBoxItem(""));
}
אני מוציא את הטבלה, רץ בלולאה על כל השורות, מחפש בעמודה המתאימה (לפי ה - DataField של ה - Combo) את המחרוזת, במידה וזה לא קיים אני מוסיף אותו.