[ASP.NET][Telerik] Get RadGrid of GridDataItem (Hashtable) convert Named Type
除了使用 FindControl 把 RadGrid 的資料撈出來,我知道的還有以下這兩種方法,可以把 Grid 上的資料撈出來轉成 Hashtable
GridDataItem.ExtractValues
GridEditableItem.OwnerTableView.ExtractValuesFromItem
在前端
使用 GridTemplateColumn 的時候要使用 Bind 或是 BindItem,不是EVal、Item
<telerik:GridTemplateColumn HeaderText="BusinessEntityID" UniqueName="BusinessEntityID" DataField="BusinessEntityID" SortExpression="BusinessEntityID"> <ItemTemplate> <asp:Label ID="Label2" runat="server" Text="<%# BindItem.BusinessEntityID %>"></asp:Label> </ItemTemplate> <EditItemTemplate> <asp:Label ID="Label2" runat="server" Text="<%# BindItem.BusinessEntityID %>"></asp:Label> </EditItemTemplate> </telerik:GridTemplateColumn>
或是 GridBoundColumn
<telerik:GridBoundColumn DataField="PersonType" FilterControlAltText="Filter PersonType column" HeaderText="PersonType" SortExpression="PersonType" UniqueName="PersonType"> <ColumnValidationSettings> <ModelErrorMessage Text=""></ModelErrorMessage> </ColumnValidationSettings> </telerik:GridBoundColumn>
在後端
透過剛剛提到的方法,將 RadGrid 的資料轉成 Hashtable,這裡我要將它再轉成強型別
protected void RadGrid1_UpdateCommand(object sender, GridCommandEventArgs e) { if (!(e.Item is GridEditableItem)) { return; } var editedItem = (GridEditableItem)e.Item; var source = new Hashtable(); editedItem.OwnerTableView.ExtractValuesFromItem(source, editedItem); var target = this._utility.ToInstance<PersonViewModel>(source); this.UpdatePerson(target); }
這裡還會用到 TypeConverterFactory 處理實值型別的轉型,請參考小朱前輩寫的 http://www.dotblogs.com.tw/regionbbs/archive/2011/11/10/orm.internals.part.2.handling.type.cast.aspx
它也處理了 Nullable<T>
public class Utility { private static Dictionary<Type, PropertyInfo[]> s_Container; public Utility() { if (s_Container == null) { s_Container = new Dictionary<Type, PropertyInfo[]>(); } } public TTarget ToInstance<TTarget>(Hashtable sources) { var targetType = typeof(TTarget); PropertyInfo[] targetPropertyInfos; if (!s_Container.ContainsKey(targetType)) { var flag = BindingFlags.Instance | BindingFlags.Public; targetPropertyInfos = targetType.GetProperties(flag); s_Container.Add(targetType, targetPropertyInfos); } else { targetPropertyInfos = s_Container[targetType]; } var targetInstance = Activator.CreateInstance<TTarget>(); foreach (DictionaryEntry source in sources) { var sourceColumnName = source.Key.ToString(); var sourceValue = source.Value; if (sourceValue == null) { continue; } foreach (var targetProperty in targetPropertyInfos) { var targetColumnName = targetProperty.Name; var targetPropertyType = targetProperty.PropertyType; if (sourceColumnName == targetColumnName) { if (targetPropertyType.IsValueType) { object typeConverterResult = null; if (IsNullable(targetPropertyType)) { var innerType = Nullable.GetUnderlyingType(targetPropertyType); typeConverterResult = GetTypeConverterResult(sourceValue, innerType); } else { typeConverterResult = GetTypeConverterResult(sourceValue, targetPropertyType); } targetProperty.SetValue(targetInstance, typeConverterResult, null);//Type Convert } else { targetProperty.SetValue(targetInstance, sourceValue); } break; } } } return targetInstance; } private object GetTypeConverterResult(object sourceValue, Type targetPropertyType) { ITypeConverter typeConverter = TypeConverterFactory.GetConvertType(targetPropertyType); object typeConverterResult; if (!targetPropertyType.IsEnum) { typeConverterResult = typeConverter.Convert(sourceValue); } else { EnumConverter converter = typeConverter as EnumConverter; typeConverterResult = converter.Convert(targetPropertyType, sourceValue); } return typeConverterResult; } private bool IsNullable(Type type) { return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>).GetGenericTypeDefinition(); ; } }
以上是小小的心得跟成果,分享給需要的人
文章出自:http://www.dotblogs.com.tw/yc421206/archive/2014/12/31/147889.aspx
若有謬誤,煩請告知,新手發帖請多包涵
Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET