I have web services that return XML defining columns and rows for a result set. Each set contains a variable number of columns and rows. I need to bind such contents to a DataGrid. However, the ItemSource property takes a collection data objects with
each object essentially a struct or class detailing the members that should be displayed on each row of the grid. I've tried parsing the XML into a collection of rows with each row defined by an array of objects. For example: object[][] or List<object[]>.
However, when I assign such a list to the ItemSource, it fails to bind. I've also tried creating a list of dynamic row objects. Each row object is a dynamic class created by reflection via Emit that holds all the columns for a row. Binding this list to
the DataGrid.ItemSource property also fails.
How do I dynamically assign a collection of rows to a DataGrid without using a pre-defined class or struct to hold the contents of each row?
Perhaps the problem is in the code that generates the class used to hold the data for each row in the generic list. Here's the method in the data class that takes the contents of the column collection, generates the dynamic data object, and then builds
a collection of such objects for each row.
Woot! Solved my own problem! The DataGrid uses reflection on properties NOT fields. I changed my dynamic type to provide properties and the DataGrid binding issue was resolved.
I have the same problem and able to solve the issue using WJAMESLORD method with little changes.
I have used property instead of field.
But i put this functionality at server side (WCF) and my service method return arry of Object. I am posting my code, please feel free to comment on this.
//method called by silverlight client... (WCF service method)
public object[] GetComponentData(string queryString, bool authflag) {
DataTable dt = ComponentHelper.GetComponentData(queryString, ref authflag); dt.TableName = "IterationResult"; Object[] rows = CreateItemsSource(dt); // method used to convert datatable row to object. return rows; // return Object array to silverlight client }
// Last, we must map the two methods created above to our PropertyBuilder to // their corresponding behaviors, "get" and "set" respectively. propBldr.SetGetMethod(getPropMthdBldr); propBldr.SetSetMethod(setPropMthdBldr);
} _RowClass = tb.CreateType(); object[] itemsSource = new object[dt.Rows.Count]; for (int rowIdx = 0; rowIdx < dt.Rows.Count; rowIdx++) { object row = Activator.CreateInstance(_RowClass); columns = dt.Columns.GetEnumerator(); int i = 0; while (columns.MoveNext()) { DataColumn info = (DataColumn)columns.Current;
PropertyInfo field = _RowClass.GetProperty(info.ColumnName.Replace(' ', '_')); object val = dt.Rows[rowIdx][i++]; //IFormatProvider format = // new CultureInfo("en-GB", true); field.SetValue(row, Convert.ChangeType(val, field.PropertyType),null); }
WJamesLord
Member
138 Points
121 Posts
Issue Binding XML to DataGrid
Mar 14, 2008 12:15 AM | LINK
I have web services that return XML defining columns and rows for a result set. Each set contains a variable number of columns and rows. I need to bind such contents to a DataGrid. However, the ItemSource property takes a collection data objects with each object essentially a struct or class detailing the members that should be displayed on each row of the grid. I've tried parsing the XML into a collection of rows with each row defined by an array of objects. For example: object[][] or List<object[]>. However, when I assign such a list to the ItemSource, it fails to bind. I've also tried creating a list of dynamic row objects. Each row object is a dynamic class created by reflection via Emit that holds all the columns for a row. Binding this list to the DataGrid.ItemSource property also fails.
How do I dynamically assign a collection of rows to a DataGrid without using a pre-defined class or struct to hold the contents of each row?
W James
WJamesLord
Member
138 Points
121 Posts
Re: Issue Binding XML to DataGrid
Mar 14, 2008 11:17 AM | LINK
Perhaps the problem is in the code that generates the class used to hold the data for each row in the generic list. Here's the method in the data class that takes the contents of the column collection, generates the dynamic data object, and then builds a collection of such objects for each row.
public object[] CreateItemsSource(){
if (_RowClass == null){
AssemblyName an = new AssemblyName("Result" + this.GetHashCode()); AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run); ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule"); TypeBuilder tb = moduleBuilder.DefineType("RowType" + this.GetHashCode(),
TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout,
typeof(object)); ConstructorBuilder constructor = tb.DefineDefaultConstructor( MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName); Dictionary<string, ColumnInfo>.Enumerator columns = GetColumnEnumerator();while (columns.MoveNext()){
ColumnInfo info = columns.Current.Value; tb.DefineField(info.ColumnName.Replace(' ', '_'), info.DataType, FieldAttributes.Public);}
_RowClass = tb.CreateType();
}
object[] itemsSource = new object[_ResultSet.Count];for (int rowIdx = 0; rowIdx < _ResultSet.Count; rowIdx++){
object row = Activator.CreateInstance(_RowClass); Dictionary<string, ColumnInfo>.Enumerator columns = GetColumnEnumerator();while (columns.MoveNext()){
ColumnInfo info = columns.Current.Value; FieldInfo field = _RowClass.GetField(info.ColumnName.Replace(' ', '_')); object val = _ResultSet[rowIdx][info.Index]; field.SetValue(row, ChangeType(val, field.FieldType));}
itemsSource[rowIdx] = row;
}
return itemsSource;}
If anyone can provide insight into this issue, I'd be very grateful.
Thanks much,
W James
WJamesLord
Member
138 Points
121 Posts
Re: Issue Binding XML to DataGrid
Mar 14, 2008 01:44 PM | LINK
Woot! Solved my own problem! The DataGrid uses reflection on properties NOT fields. I changed my dynamic type to provide properties and the DataGrid binding issue was resolved.
W James
dotnetmac
Member
28 Points
19 Posts
Re: Re: Issue Binding XML to DataGrid
Mar 19, 2008 05:23 PM | LINK
Hey bro,
i have the same issue with my project, can you please post the code.
Thanx in advance
GunnarHoffmann
Member
4 Points
2 Posts
Re: Issue Binding XML to DataGrid
Apr 28, 2008 06:23 PM | LINK
Can you please provide the source code for this problem?
Thanks in advance
GH
avtar
Participant
777 Points
208 Posts
Re: Issue Binding XML to DataGrid
Jan 06, 2009 04:35 AM | LINK
Hello and a very happy new year to all.
I have the same problem and able to solve the issue using WJAMESLORD method with little changes.
I have used property instead of field.
But i put this functionality at server side (WCF) and my service method return arry of Object. I am posting my code, please feel free to comment on this.
Thanks to all.
Avtar.
avtar
Participant
777 Points
208 Posts
Re: Issue Binding XML to DataGrid
Jan 06, 2009 08:45 AM | LINK
Hi,
now my wcf method return array of Object..i.e (object[]) but getting Communication Exception at client side.
http://silverlight.net/forums/t/63057.aspx
Avtar.