[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