本文主要介紹從RadGrid獲取綁定的值,僅適用於Telerik RadControls for asp.net ajax。html
RadGrid把綁定的值存儲在VIewState中,即便ViewState被禁用依然會生成相應的ViewState值;它主要提供了兩種方式來獲取綁定的值:git
使用此功能必須先給RadGrid的MasterTableView設置DataKeyNames,能夠設置多個字段(中間用逗號隔開):github
<MasterTableView DataKeyNames="Id,Id2">
一旦設置好DataKeyNames,全部設置的字段值均可以從RadGrid.MasterTableView.DataKeyValues屬性(Hashtable類型)獲取,只須要指定行以及字段名稱:web
rg.MasterTableView.DataKeyValues[0]["Id"]; // 獲取第一行綁定的Id值 rg.Items[0].GetDataKeyValue("Id"); // 獲取第一行的Id值
其中DataKeyValues屬性中的Key都是字符串,Value與綁定的對象屬性類型同樣(好比都是DateTime)。ajax
須要注意:獲取的時候字段名稱必須與DataKeyNames中設置的同樣,並且必須區分大小寫。若是不想區分大小寫,則能夠用如下方法:api
var ht = rg.MasterTableView.DataKeyValues[0]; var ht2 = new Hashtable(ht, StringComparer.OrdinalIgnoreCase); var value1 = ht2["id"];
也能夠直接遍歷DataKeyValues屬性的全部Key再獲取對應的值。asp.net
還須要注意:DataKeyValues的值存儲在ViewState中,設置越多的DataKeyNames將會使ViewState內容增大,因此,如無必要,應當儘量少的設置DataKeyNames裏面的字段。ide
前臺必須使用GridBoundColumn或者它的子類如:GridDateTimeColumn等進行數據綁定:ui
<telerik:GridDateTimeColumn HeaderText="..." DataField="..." /> <telerik:GridBoundColumn HeaderText="..." DataField="..." />
獲取值的方法顯得有點麻煩,須要先把當前行各個列的值提取出來,並存入任意IDictionary的子類當中,而後再從Dictionary中獲取特定的值:this
var dict = new HybridDictionary(true); var dict = new Hashtable(StringComparer.OrdinalIgnoreCase); var dict = new ListDictionary(StringComparer.OrdinalIgnoreCase); var dict = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); var item = rg.Items[0]; // 第一行 item.ExtractValues(dict); // 以上任意一個dict var value = dict["Id"]; // 獲取Id值
是否區分大小寫取決於Dictionary初始化方法,另外,無論綁定的時候屬性是什麼類型的,提取出來的Dictionary的全部Key和Value都是string類型。
這也是asp.net通用的方法,全部數據列表如GridView、Repeater都支持這種方法來獲取。
比較簡單的方法是使用Column的UniqueName來獲取對應的TableCell,再從TableCell獲取值。
首先設置Column的UniqueName(僅用於後臺獲取):
<telerik:GridBoundColumn UniqueName="id" ...> <telerik:GridDateTimeColumn UniqueName="id2" ...>
而後在後臺經過UniqueName獲取值:
var idCell = rg.Items[0]["id"]; // Column的UniqueName var value1 = idCell.Text;
固然,也能夠不設置UniqueName,直接經過Column的序號來獲取對應的TableCell值:
var idCell2 = rg.Items[0][rg.Columns[0]]; // 直接按序號獲取Column,再獲取對應的Cell var value2 = idCell2.Text;
這種方法須要預先知道Column的序號,用起來也不太方便;並且,萬一Column的順序改變了,還得去調整對應的代碼,至關不靈活。
從TableCell獲取值這種方法僅適用於GridBoundColumn以及它的子類,對於GridTemplateColumn則必須使用查找控件的辦法來獲取值。
前臺聲明:
<telerik:GridTemplateColumn UniqueName="idCol" HeaderText="編號"> <ItemTemplate> <asp:Literal runat="server" ID="idText" Text='<%#Eval("id") %>' /> </ItemTemplate> </telerik:GridTemplateColumn>
後臺須要先找到控件再獲取值:
var idCell = rg.Items[0]["idCol"]; // 找到Column var idText = idCell3.FindControl("idText") as Literal; // 找到Literal控件 //var idText = rg.Items[0].FindControl("idText") as Literal; // 以上兩步也能夠省略爲這樣,前臺就不須要設置UniqueName var value = idText.Text; // 從Literal獲取值
此外,RadGrid還提供了許多客戶端API,使用方法與服務端相似,使用DataKeyValues時須要設置ClientDataKeyNames,具體請看(http://www.telerik.com/help/aspnet-ajax/grid-getting-familiar-with-client-side-api.html),這裏再也不詳細描述。
獲取當前操做的行綁定的值,須要操做的按鈕在當前行內,一般與RadGrid的ItemCommand、以及從ItemCommand衍生的DeleteCommand等相關。
前臺聲明:
<telerik:GridTemplateColumn HeaderText="操做"> <ItemTemplate> <asp:Button CommandName="Command1" runat="server" Text="操做1" /> <asp:Button CommandName="Command2" runat="server" Text="操做2" /> <asp:Button CommandName="Delete" runat="server" Text="刪除" /> </ItemTemplate> </telerik:GridTemplateColumn>
在後臺對應的事件中獲取:
protected void rg_ItemCommand(object sender, GridCommandEventArgs e) { if (e.Item.ItemType == GridItemType.Item || e.Item.ItemType == GridItemType.AlternatingItem) { var currentItem = rg.Items[e.Item.ItemIndex]; // 獲取當前行 var currentItem = e.Item as GridDataItem; // e.Item就是當前行, 在當前操做中其實是GridDataItem類型 // 經過DataKeyValues獲取 var value = currentItem.GetDataKeyValue("Id"); var value = rg.MasterTableView.DataKeyValues[currentItem.ItemIndex]["Id"]; // 經過ExtractValues獲取 var dict = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); currentItem.ExtractValues(dict); var value = dict["Id"]; // 經過TableCell獲取 var value = currentItem["idCol"].Text; // GridBoundColumn var value = (currentItem.FindControl("idText") as Literal).Text; // GridTemplateColumn } }
在ItemCommand的事件中還須要注意判斷ItemType,而在更具體的事件如DeleteCommand中則無此必要。
這種獲取的方式顯得更加簡單方便,而傳統的辦法則顯得比較麻煩:
<asp:Button CommandName="Command1" CommandArgument='<%#Eval("id") %>' runat="server" Text="操做1" />
protected void rg_ItemCommand(object sender, GridCommandEventArgs e) { if (e.Item.ItemType == GridItemType.Item || e.Item.ItemType == GridItemType.AlternatingItem) { var value = e.CommandArgument; } }
特別是操做按鈕多的時候,傳統的辦法須要每一個按鈕都綁定,不只麻煩並且也浪費資源。
要使RadGrid能選中行,必須確保開啓了ViewState(不然沒法獲取選中的行),而後開啓容許選中屬性:
<telerik:RadGrid ...> <ClientSettings> <Selecting AllowRowSelect="true" /> </ClientSettings>
(可選)還能夠增長一個選擇列以幫助選擇:
<Columns> <telerik:GridClientSelectColumn />
var selectedItem = rg.SelectedItems[0] as GridDataItem; // 當前選中項 var selectedItem = rg.Items[int.Parse(rg.SelectedIndexes[0])]; // 當前選中項 // 經過DataKeyValues獲取 var value = rg.SelectedValue; // 獲取DataKeyNames第一個字段的值 var values = rg.SelectedValues; // 獲取全部DataKeyNames字段的值,返回Hashtable var idValue = values["Id"]; var value = selectedItem.GetDataKeyValue("Id"); var value = rg.MasterTableView.DataKeyValues[selectedItem.ItemIndex]["Id"]; // 經過ExtractValues獲取 var dict = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); selectedItem.ExtractValues(dict); var value = dict["id"]; // 經過TableCell獲取 var value = selectedItem["idCol"].Text; // GridBoundColumn var value = (selectedItem.FindControl("idText") as Literal).Text; // GridTemplateColumn
能夠看出,方法與獲取當前行綁定的值同樣,無非是RadGrid多了兩個屬性:SelectedValue和SelectedValues。
要使RadGrid能選中多行,須要先開啓AllowMultiRowSelection屬性。獲取數據的方法與獲取單行選中的值差很少:
// 經過DataKeyValues獲取 foreach (GridDataItem item in rg.SelectedItems) { var value = item.GetDataKeyValue("Id"); var value = rg.MasterTableView.DataKeyValues[item.ItemIndex]["Id"]; } foreach (string item in rg.SelectedIndexes) { var value = rg.MasterTableView.DataKeyValues[int.Parse(item)]["Id"]; var value = rg.Items[int.Parse(item)].GetDataKeyValue("Id"); } // 經過ExtractValues獲取 foreach (GridDataItem item in rg.SelectedItems) { var dict = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); item.ExtractValues(dict); var value = dict["Id"]; } foreach (string item in rg.SelectedIndexes) { var dict = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); rg.Items[int.Parse(item)].ExtractValues(dict); var value = dict["Id"]; } // 經過TableCell獲取 foreach (GridDataItem item in rg.SelectedItems) { var value = item["idCol"].Text; // GridBoundColumn var value = (item.FindControl("idText") as Literal).Text; // GridTemplateColumn } foreach (string item in rg.SelectedIndexes) { var value = rg.Items[int.Parse(item)]["idCol"].Text; // GridBoundColumn var value = (rg.Items[int.Parse(item)].FindControl("idText") as Literal).Text; // GridTemplateColumn }
主要是使用RadGrid的SelectedItems屬性,或者SelectedIndexes配合Items屬性使用,實際上SelectedItems也是這兩個屬性配合使用而產生的集合,內部實現以下:
public GridItemCollection SelectedItems { get { GridItemCollection gridItemCollection = new GridItemCollection(); foreach (string hierarchicalIndex in this.SelectedIndexes) { gridItemCollection.Add(this.Items[hierarchicalIndex]); } return gridItemCollection; } }
以上這些方法獲取綁定值的邏輯都是同樣的,在實際使用的時候若是仍是這樣子去寫顯得太過繁瑣,因此封裝成如下擴展方法:
/// <summary> /// RadGrid擴展方法 /// by lwme.cnblogs.com /// </summary> public static class RadGridExtensions_By_Lwme_Cnblogs_com { /// <summary> /// 提取值 /// </summary> /// <param name="item"></param> /// <returns></returns> public static Dictionary<string, string> ExtractValuesFromItem(this GridItem item) { var dict = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); // 不區分大小寫 var dataItem = item as GridEditableItem; if (dataItem != null) { dataItem.ExtractValues(dict); } return dict; } /// <summary> /// 提取值 /// </summary> /// <param name="item"></param> /// <param name="key"></param> /// <returns></returns> public static string ExtractValueFromItem(this GridItem item, string key) { var dict = ExtractValuesFromItem(item); if (dict.ContainsKey(key)) return dict[key]; return null; } /// <summary> /// 提取值 /// </summary> /// <param name="item"></param> /// <returns></returns> public static Hashtable ExtractValuesFromTableView(this GridItem item) { return new Hashtable(item.OwnerTableView.DataKeyValues[item.ItemIndex], StringComparer.OrdinalIgnoreCase); } /// <summary> /// 提取值 /// </summary> /// <param name="item"></param> /// <param name="key"></param> /// <returns></returns> public static object ExtractValueFromTableView(this GridItem item, string key) { var dict = ExtractValuesFromTableView(item); if (dict.Contains(key)) return dict[key]; return null; } /// <summary> /// 忽略大小寫比較 /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> public static bool IgnoreCaseCompare(this string a, string b) { return string.Compare(a, b, StringComparison.OrdinalIgnoreCase) == 0; } /// <summary> /// 提取值 /// </summary> /// <param name="item"></param> /// <param name="key"></param> /// <returns></returns> public static string ExtractValueFromTableCell(this GridItem item, string key) { var dataItem = item as GridEditableItem; foreach (GridColumn col in dataItem.OwnerTableView.OwnerGrid.Columns) { var boundCol = col as GridBoundColumn; if (boundCol != null && (boundCol.UniqueName.IgnoreCaseCompare(key) || boundCol.DataField.IgnoreCaseCompare(key) || boundCol.SortExpression.IgnoreCaseCompare(key))) { return dataItem[key].Text; } var tempCol = col as GridTemplateColumn; if (tempCol != null && (tempCol.UniqueName.IgnoreCaseCompare(key) || tempCol.DataField.IgnoreCaseCompare(key) || tempCol.SortExpression.IgnoreCaseCompare(key))) { var textCtrl = item.FindControl(key) as ITextControl; if (textCtrl != null) return textCtrl.Text; } } return null; } /// <summary> /// 提取值 /// </summary> /// <param name="item"></param> /// <param name="key"></param> /// <returns></returns> public static object ExtractValue(this GridItem item, string key = null) { var keyNames = item.OwnerTableView.DataKeyNames; bool hasKeys = keyNames.Length > 0; if (hasKeys && key == null) key = keyNames[0]; object value = null; if (hasKeys) value = ExtractValueFromTableView(item, key); if (value == null) { var strValue = ExtractValueFromItem(item, key); if (string.IsNullOrEmpty(strValue)) strValue = ExtractValueFromTableCell(item, key); if (!string.IsNullOrEmpty(strValue)) value = strValue; } return value; } /// <summary> /// 提取值 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="item"></param> /// <param name="key"></param> /// <returns></returns> public static T ExtractValue<T>(this GridItem item, Func<string, T> cast, string key = null) { var result = ExtractValue(item, key); if (result == null) return default(T); if (result.GetType() == typeof(string)) return cast(result.ToString()); return (T)result; } /// <summary> /// 提取值 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="e"></param> /// <param name="key"></param> /// <returns></returns> public static T ExtractValue<T>(this GridCommandEventArgs e, Func<string, T> cast, string key = null) { return ExtractValue<T>(e.Item, cast, key); } /// <summary> /// 提取選中的多個值 /// </summary> /// <param name="grid"></param> /// <returns></returns> public static List<object> ExtractSelected(this RadGrid grid, string key = null) { var items = grid.SelectedItems; var result = new List<object>(items.Count); foreach (GridDataItem item in items) { object value = ExtractValue(item, key); if (value != null) result.Add(value); } return result; } /// <summary> /// 提取選中的多個值 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="grid"></param> /// <param name="key"></param> /// <returns></returns> public static List<T> ExtractSelected<T>(this RadGrid grid, Func<string, T> cast, string key = null) { var items = grid.SelectedItems; var result = new List<T>(items.Count); foreach (GridDataItem item in items) { T value = ExtractValue<T>(item, cast, key); if (value != null) result.Add(value); } return result; } }
這樣也能應付大多數狀況了,使用的時候注意類型就能夠了。
protected void rg_ItemCommand(object sender, GridCommandEventArgs e) { object value = e.Item.ExtractValue(); // 默認的DataKeyNames第一個字段 Guid value = e.ExtractValue<Guid>(value => new Guid(value)); // 自定義轉換方法 string value = e.ExtractValue<string>(value => value, "Id2"); // 顯式指定字段 Guid value = e.ExtractValue<Guid>(value => new Guid(value), "Id3"); int value = e.ExtractValue<int>(value => int.Parse(value), "Id4"); }
List<object> values = rg.ExtractSelected(); // 默認的DataKeyNames第一個字段 List<Guid> values = rg.ExtractSelected<Guid>(value => new Guid(value)); // 自定義轉換方法 List<string> values = rg.ExtractSelected<string>(value => value, "Id2"); // 顯式指定字段 List<Guid> values = rg.ExtractSelected<Guid>(value => new Guid(value), "Id3"); List<int> values = rg.ExtractSelected<int>(value => int.Parse(value), "Id4");
這樣簡化以後,使用起來也變得更加簡單了。
所有代碼提供在GitHub:https://github.com/corminlu/radcontrols-extensions/