• RadGrid使用技巧:从RadGrid获取绑定的值


    本文主要介绍从RadGrid获取绑定的值,仅适用于Telerik RadControls for asp.net ajax。

    获取方式

    RadGrid把绑定的值存储在VIewState中,即使ViewState被禁用依然会生成相应的ViewState值;它主要提供了两种方式来获取绑定的值:

    1.从绑定的DataKeyValues获取

    使用此功能必须先给RadGrid的MasterTableView设置DataKeyNames,可以设置多个字段(中间用逗号隔开):

    <MasterTableView DataKeyNames="Id,Id2">

    一旦设置好DataKeyNames,所有设置的字段值都可以从RadGrid.MasterTableView.DataKeyValues属性(Hashtable类型)获取,只需要指定行以及字段名称:

    rg.MasterTableView.DataKeyValues[0]["Id"]; // 获取第一行绑定的Id值
    rg.Items[0].GetDataKeyValue("Id"); // 获取第一行的Id值

    其中DataKeyValues属性中的Key都是字符串,Value与绑定的对象属性类型一样(比如都是DateTime)。

    需要注意:获取的时候字段名称必须与DataKeyNames中设置的一样,而且必须区分大小写。如果不想区分大小写,则可以用以下方法:

    var ht = rg.MasterTableView.DataKeyValues[0];
    var ht2 = new Hashtable(ht, StringComparer.OrdinalIgnoreCase);
    var value1 = ht2["id"];

    也可以直接遍历DataKeyValues属性的所有Key再获取对应的值。

    还需要注意:DataKeyValues的值存储在ViewState中,设置越多的DataKeyNames将会使ViewState内容增大,所以,如无必要,应当尽可能少的设置DataKeyNames里面的字段。

    2.从绑定列ExtractValues获取

    前台必须使用GridBoundColumn或者它的子类如:GridDateTimeColumn等进行数据绑定:

    <telerik:GridDateTimeColumn HeaderText="..." DataField="..." />
    <telerik:GridBoundColumn HeaderText="..." DataField="..." />  

    获取值的方法显得有点麻烦,需要先把当前行各个列的值提取出来,并存入任意IDictionary的子类当中,然后再从Dictionary中获取特定的值:

    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类型。

    额外的方法:从TableCell获取

    这也是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的顺序改变了,还得去调整对应的代码,相当不灵活。

    GridTemplateColumn的特殊处理

    从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/

  • 相关阅读:
    前缀和
    B. Ilya and Queries
    BZOJ1652 [Usaco2006 Feb]Treats for the Cows
    NOIP2014提高组 酱油记
    NOIP初赛 BLESS ALL!
    BZOJ1096 [ZJOI2007]仓库建设
    BZOJ1036 [ZJOI2008]树的统计Count
    BZOJ1030 [JSOI2007]文本生成器
    BZOJ2749 [HAOI2012]外星人
    BZOJ1093 [ZJOI2007]最大半连通子图
  • 原文地址:https://www.cnblogs.com/lwme/p/radgrid-tips-extract-values.html
Copyright © 2020-2023  润新知