This question is locked. New answers and comments are not allowed.
I would like Telerik's Grid to bind to a property but to an array that's indexed using strings. This implies that the properties and its value types are dynamic. However, every example i have seen on Telerik's website, the Grid only binds to static class.
Is there way i can get the Grid to bind to a dynamic object?
Is there way i can get the Grid to bind to a dynamic object?
2 Answers, 1 is accepted
0

Jo
Top achievements
Rank 1
answered on 29 Mar 2012, 10:07 PM
Hello,
Did you ever find a solution to this?
I am currently playing around with whether or not it is possible to create my grid's model dynamically and at the same time allow the user to perform CRUD operations against the records.
Did you ever find a solution to this?
I am currently playing around with whether or not it is possible to create my grid's model dynamically and at the same time allow the user to perform CRUD operations against the records.
To give an idea of the problem domain, the flow of operation goes as such: 1) The application will display a list of tables the user can select from 2) User selects the table he/she wants to work with 3) Application requests the database to return the table's schema 4) Application builds the model based on the returned schema 5) Application requests the records for the selected table and displays on grid.
The issue I am seeing with the code below, is that when I click on the "Update" button for the row I want to edit, the grid cell disappears. The column name persists as well as the underlying value of the data item. I even implemented a callback for the grid's OnEdit() event to confirm that the value is still there (ID) and it is, but the cell that holds the content is gone. - Does anybody have an idea why this is so?
Also, are ExpandoObject or DynamicObject good candidates to explore for the problem domain?
View
@model IEnumerable<object>
@(Html.Telerik().Grid(Model)
.Name("Grid")
.DataKeys(keys => keys.Add("ID"))
.ClientEvents(events => events.OnEdit("grid_onEdit"))
.Columns(columns =>
{
// Column name will come from the schema
columns.Bound("ID");
columns.Command(command => command.Edit());
})
.DataBinding(dataBinding => dataBinding.Ajax().Select("Get", "Home").Update("Save", "Home"))
.Pageable()
.Sortable()
.Scrollable()
.Groupable()
.Filterable()
.Editable(editable => editable.TemplateName("ManualEntry").Mode(GridEditMode.InForm))
)
<
script
type
=
"text/javascript"
>
function grid_onEdit(e) {
var dataItem = e.dataItem;
// I am getting the value back, but the cell disappeared.
alert(dataItem.ID);
}
</
script
>
Controller:
[GridAction]
public ActionResult Get()
{
GridModel model = new GridModel
{
Data = GetObjects()
};
return View(model);
}
// build my list of dynamically-created objects
private IEnumerable<
object
> GetObjects()
{
int index;
IList<
object
> instanceCollection = new List<
object
>();
for (index = 0; index <
5
; index++)
{
// "index" is just the placeholder for the property's value
instanceCollection.Add(GetInstance(index));
}
return instanceCollection;
}
private object GetInstance(int value)
{
// build object
AssemblyName assemblyName = new AssemblyName();
assemblyName.Name = "tmpAssembly";
AssemblyBuilder assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
ModuleBuilder module = assemblyBuilder.DefineDynamicModule("tmpModule");
// create a new type builder
TypeBuilder typeBuilder = module.DefineType("ManualEntryCollection", TypeAttributes.Public | TypeAttributes.Class);
// Loop over the attributes that will be used as the properties names in out new type
//foreach (XmlNode node in xmlDoc.SelectSingleNode("root").ChildNodes)
//{
string propertyName = "ID";
// Generate a private field
FieldBuilder field = typeBuilder.DefineField("_" + propertyName, typeof(string), FieldAttributes.Private);
// Generate a public property
PropertyBuilder property =
typeBuilder.DefineProperty(propertyName,
PropertyAttributes.None,
typeof(string),
new Type[] { typeof(string) });
// The property set and property get methods require a special set of attributes:
MethodAttributes GetSetAttr =
MethodAttributes.Public |
MethodAttributes.HideBySig;
// Define the "get" accessor method for current private field.
MethodBuilder currGetPropMthdBldr =
typeBuilder.DefineMethod(propertyName, GetSetAttr, typeof(string), Type.EmptyTypes);
// Intermediate Language stuff...
ILGenerator currGetIL = currGetPropMthdBldr.GetILGenerator();
currGetIL.Emit(OpCodes.Ldarg_0);
currGetIL.Emit(OpCodes.Ldfld, field);
currGetIL.Emit(OpCodes.Ret);
// Define the "set" accessor method for current private field.
MethodBuilder currSetPropMthdBldr =
typeBuilder.DefineMethod(propertyName,
GetSetAttr,
null,
new Type[] { typeof(string) });
// Again some Intermediate Language stuff...
ILGenerator currSetIL = currSetPropMthdBldr.GetILGenerator();
currSetIL.Emit(OpCodes.Ldarg_0);
currSetIL.Emit(OpCodes.Ldarg_1);
currSetIL.Emit(OpCodes.Stfld, field);
currSetIL.Emit(OpCodes.Ret);
// Last, we must map the two methods created above to our PropertyBuilder to
// their corresponding behaviors, "get" and "set" respectively.
property.SetGetMethod(currGetPropMthdBldr);
property.SetSetMethod(currSetPropMthdBldr);
//}
// Generate our type
Type generetedType = typeBuilder.CreateType();
// Now we have our type. Let's create an instance from it:
object generetedObject = Activator.CreateInstance(generetedType);
// Loop over all the generated properties, and assign the values from our XML:
PropertyInfo[] properties = generetedType.GetProperties();
int propertiesCounter = 0;
// Loop over the values that we will assign to the properties
//foreach (XmlNode node in xmlDoc.SelectSingleNode("root").ChildNodes)
//{
//Random rnd = new Random();
properties[propertiesCounter].SetValue(generetedObject, value.ToString(), null);
//propertiesCounter++;
//}
//Yoopy ! Return our new genereted object.
return generetedObject;
}
I was able to use Telerik's MVC grid for my dynamically created objects, but when I attempt to edit the row, the grid cell disappears - the underlying value persists though.
{
// build object
AssemblyName assemblyName = new AssemblyName();
assemblyName.Name = "tmpAssembly";
AssemblyBuilder assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
ModuleBuilder module = assemblyBuilder.DefineDynamicModule("tmpModule");
// create a new type builder
TypeBuilder typeBuilder = module.DefineType("ManualEntryCollection", TypeAttributes.Public | TypeAttributes.Class);
// Loop over the attributes that will be used as the properties names in out new type
//foreach (XmlNode node in xmlDoc.SelectSingleNode("root").ChildNodes)
//{
string propertyName = "ID";
// Generate a private field
FieldBuilder field = typeBuilder.DefineField("_" + propertyName, typeof(string), FieldAttributes.Private);
// Generate a public property
PropertyBuilder property =
typeBuilder.DefineProperty(propertyName,
PropertyAttributes.None,
typeof(string),
new Type[] { typeof(string) });
// The property set and property get methods require a special set of attributes:
MethodAttributes GetSetAttr =
MethodAttributes.Public |
MethodAttributes.HideBySig;
// Define the "get" accessor method for current private field.
MethodBuilder currGetPropMthdBldr =
typeBuilder.DefineMethod(propertyName, GetSetAttr, typeof(string), Type.EmptyTypes);
// Intermediate Language stuff...
ILGenerator currGetIL = currGetPropMthdBldr.GetILGenerator();
currGetIL.Emit(OpCodes.Ldarg_0);
currGetIL.Emit(OpCodes.Ldfld, field);
currGetIL.Emit(OpCodes.Ret);
// Define the "set" accessor method for current private field.
MethodBuilder currSetPropMthdBldr =
typeBuilder.DefineMethod(propertyName,
GetSetAttr,
null,
new Type[] { typeof(string) });
// Again some Intermediate Language stuff...
ILGenerator currSetIL = currSetPropMthdBldr.GetILGenerator();
currSetIL.Emit(OpCodes.Ldarg_0);
currSetIL.Emit(OpCodes.Ldarg_1);
currSetIL.Emit(OpCodes.Stfld, field);
currSetIL.Emit(OpCodes.Ret);
// Last, we must map the two methods created above to our PropertyBuilder to
// their corresponding behaviors, "get" and "set" respectively.
property.SetGetMethod(currGetPropMthdBldr);
property.SetSetMethod(currSetPropMthdBldr);
//}
// Generate our type
Type generetedType = typeBuilder.CreateType();
// Now we have our type. Let's create an instance from it:
object generetedObject = Activator.CreateInstance(generetedType);
// Loop over all the generated properties, and assign the values from our XML:
PropertyInfo[] properties = generetedType.GetProperties();
int propertiesCounter = 0;
// Loop over the values that we will assign to the properties
//foreach (XmlNode node in xmlDoc.SelectSingleNode("root").ChildNodes)
//{
//Random rnd = new Random();
properties[propertiesCounter].SetValue(generetedObject, value.ToString(), null);
//propertiesCounter++;
//}
//Yoopy ! Return our new genereted object.
return generetedObject;
}
I was able to use Telerik's MVC grid for my dynamically created objects, but when I attempt to edit the row, the grid cell disappears - the underlying value persists though.
0

Jo
Top achievements
Rank 1
answered on 03 Apr 2012, 04:53 PM
I figured out exactly what the problem was.. it was such a silly mistake on my part.
I defined a template on my view which I mistakenly did not have any implementation for. :)
So... to remedy the problem I was having with the cell contents disappearing:
1) Added a folder called "Editor Templates" under Views -> Home
2) Added a partial view and implemented the controls for the columns I wish to edit.
I defined a template on my view which I mistakenly did not have any implementation for. :)
So... to remedy the problem I was having with the cell contents disappearing:
1) Added a folder called "Editor Templates" under Views -> Home
2) Added a partial view and implemented the controls for the columns I wish to edit.