One requirement to talk about WCF (4)

Source: Internet
Author: User
Tags emit

Bind data

In this article, the data retrieved from the database does not have a fixed format. As a result, the service data cannot be transmitted using a fixed static structure. To transmit such data, you need to design a data structure like system. Data. able, as shown below:

[DataContract]public class SimpleTable{    [DataMember]    public string[] Columns    { get; set; }    [DataMember]    public Row[] Rows    { get; set; }}[DataContract]public struct Row{    [DataMember]    public RowItem[] Items    { get; set; }}[DataContract]public struct RowItem{    [DataMember]    public string Name    { get; set; }    [DataMember]    public string Content    { get; set; }}

The simpletable. Columns attribute records the number of columns of data, and the data in each row is placed in simpletable. rows. In this way, any form of row and column data can be processed.

After the service passes the data to Silverlight, The DataGrid can bind the data. However, we encountered a problem where the DataGrid can bind static data while our data is dynamic. To allow the DataGrid to use the data, I have thought of the following two methods:

1. Use List <Object> as the data source. Put anonymous objects in the Data source:

List<object> list = new List<object>();foreach (Row row in Rows){    list.Add(new { ColumnName1 = row.column1Value, ColumnName2 = row.column2Value });}

In practice, we will find that this does not work at all. This practice requires that columnname can be directly written into the simple name in the code, but our columnname is dynamic. In this case, the eval mechanism similar to JavaScript may be useful, but it is not easy to implement this mechanism before the. NET compiler acts as a service (complier as a servie) function is introduced. The most important thing is that even if we can do it, we should not do it like this. In this way, we will complicate the original problem because it is at the tip of the corner and will be overly-designed and go astray.

2. Use List <dynamic> as the data source, and put the expandoobject object in the Data source:

List<dynamic> list = new List<dynamic>();foreach (Row row in Rows){    dynamic data = new ExpandoObject();    (data as ICollection<KeyValuePair<string, object>>).Add(new KeyValuePair<string, object>(row.columnName, row.columaValue));    list.Add(data);}

In this case, there are no 1st methods, but they still fail. The DataGrid does not recognize the dynamic data type.

It seems that dynamic data sources do not work. If static data must be used, there is one more link: static data can also be dynamically created using code .. NET provides a "Reflection and emission" mechanism that can use code to generate an assembly, module, class, method, and so on in a program.

The following are the specific practices:

Public static ienumerable getdatagridsource (simpletable) {// dynamically defines the Assembly, module, class assemblyname = new assemblyname ("dynamicgridviewmodelassembly"); assemblybuilder = appdomain. currentdomain. definedynamicassembly (assemblyname, assemblybuilderaccess. run); modulebuilder = assemblybuilder. definedynamicmodule ("dynamicgridviewmodelmodule"); typebuilder = modulebuilder. definetype ("dynamicgridviewmodeltype", typeattributes. public); // constructorbuilder = typebuilder. defineconstructor (methodattributes. public, callingconventions. standard, type. emptytypes); ilgenerator constructoril = constructorbuilder. getilgenerator (); constructoril. emit (Opcodes. ldarg_0); constructoril. emit (Opcodes. call, typeof (object ). getconstructor (type. emptytypes); constructoril. emit (Opcodes. RET); // dynamically defines the attributes of the class. Each attribute corresponds to a column of foreach (string column in simpletable. columns) {fieldbuilder fieldbuidler = typebuilder. definefield ("M _" + column, typeof (string), fieldattributes. private); propertybuilder = typebuilder. defineproperty (column, propertyattributes. hasdefault, typeof (string), null); methodattributes = methodattributes. public | methodattributes. specialname | methodattributes. hidebysig; methodbuilder methodgetbuilder = typebuilder. definemethod ("Get _" + column, methodattributes, typeof (string), type. emptytypes); ilgenerator methodgetil = methodgetbuilder. getilgenerator (); methodgetil. emit (Opcodes. ldarg_0); methodgetil. emit (Opcodes. ldfld, fieldbuidler); methodgetil. emit (Opcodes. RET); methodbuilder methodsetbuilder = typebuilder. definemethod ("SET _" + column, methodattributes, null, new type [] {typeof (string)}); ilgenerator methodsetil = methodsetbuilder. getilgenerator (); methodsetil. emit (Opcodes. ldarg_0); methodsetil. emit (Opcodes. ldarg_1); methodsetil. emit (Opcodes. stfld, fieldbuidler); methodsetil. emit (Opcodes. RET); propertybuilder. setgetmethod (methodgetbuilder); propertybuilder. setsetmethod (methodsetbuilder);} // dynamically creates a class type modeltype = typebuilder. createtype (); Type listtype = typeof (list <> ). makegenerictype (modeltype); Object List = activator. createinstance (listtype); methodinfo methodadd = listtype. getmethod ("add"); // dynamically creates a class instance. Each instance corresponds to a row of foreach (Row row in simpletable. rows) {object model = activator. createinstance (modeltype); foreach (rowitem item in row. items) {propertyinfo = modeltype. getproperty (item. name); propertyinfo. setvalue (model, item. content, null);} methodadd. invoke (list, new object [] {model});} return (ienumerable) list ;}

This method is used to create the data source of the DataGrid, although the type is dynamic, but it is indeed static: List <dynamicgridviewmodeltype>, so you can bind it:

client.GetTableCompleted += (s, a) =>{    dataGrid1.ItemsSource = GetDataGridSource(a.Result);};client.GetTableAsync("ExampleTable");

In fact, this solution is not intuitive and simple, but I cannot find a more reliable solution.

By now, the task of binding dynamic types to the Silverlight DataGrid has been completed, and the entire requirement has been completed. If you have any suggestions or guidance, please advise. Thank you.

 

Example: http://download.csdn.net/detail/wantalcs/4494183

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.