Use List in Silverlight to construct a cross table as the data source of the Silverlight DataGrid

Source: Internet
Author: User

Problem origin: A colleague retrieves the data of a table, constructs a cross table based on the selected monitoring factor and region, and binds it to the Silverlight DataGrid. He has no clue, I will help solve this problem.

Solution:

1. the best way is to build a cross-tabulation when obtaining data. You can build two types of cross-tabulation, one being column-specific and the other being dynamic columns, can be built through SQL, so I won't complain here.

2. My colleague said that the data object has been obtained and does not want to modify the code. It is also because the entity built with ibatis.net is used. If a dynamic cross table is built, the entity-Layer Code must indeed be quite changed. Finally, we decided to write C # code on the client to build a cross table data source and bind it to the DataGrid.

The itemssource of the DataGrid requires an object that implements ienumerable.

Requirements:

Multiple factors can be selected: A, B, C...

You can select multiple regions: Guangzhou, Foshan, and Shenzhen.

Data retrieved:

Regional monitoring factor value

Guangzhou a A11

Guangzhou B B22

Guangzhou D d33

Foshan A A44

Foshan C c55

Select "a, B, c" and "Guangzhou, Foshan, and Shenzhen ":

Select "A, B" and "Guangzhou, Foshan, and Shenzhen ":

Test code:

 

// Multiple factors selected
String [] monitoringfactor = new string [] {"A", "B", "C "};
// Select multiple regions
String [] area = new string [] {"Guangzhou", "Foshan", "Shenzhen "};
// Construct an array of simulated data if the actual table is not retrieved
String [] [] factordata = new string [5] [];
Factordata [0] = new string [] {"Guangzhou", "A", "A11 "};
Factordata [1] = new string [] {"Guangzhou", "B", "B22 "};
Factordata [2] = new string [] {"Guangzhou", "D", "d33 "};
Factordata [3] = new string [] {"Foshan", "A", "A44 "};
Factordata [4] = new string [] {"Foshan", "C", "c55 "};

// Xgrid is a DataGrid Control name

Xgrid. itemssource = binddata (monitoringfactor, area, factordata). todatasource ();

 

Public ienumerable <idictionary> binddata (string [] factor, string [] area, string [] [] factordata)
{
// Construct the cross table data and return ienumerable <idictionary>
For (Int J = 0; j <area. length; j ++)
{
Int m = 0;
VaR returndictionary = new dictionary <string, Object> ();
For (INT I = 0; I <factor. length; I ++)
{
Int x = 0;
For (int K = 0; k <factordata. length; k ++)
{
If (factordata [k] [0]. tostring () = area [J]. tostring () & factordata [k] [1] = factor [I]. tostring ())
{
X = x + 1;
If (M = 0)
{
Returndictionary ["region"] = area [J]. tostring ();
}
Returndictionary [factor [I]. tostring ()] = factordata [k] [2]. tostring ();
M = m + 1;
}
}
If (x = 0)
{
Returndictionary [factor [I]. tostring ()] = "0 ";
}
If (M = 0 & X = 0)
{
Returndictionary ["region"] = area [J]. tostring ();
Returndictionary [factor [I]. tostring ()] = "0 ";
}
}
Yield return returndictionary;
}
}

 

Public static class extends cecreator
{
Private Static readonly dictionary <string, type> _ typebysigniture = new dictionary <string, type> ();

Public static ienumerable todatasource (this ienumerable <idictionary> List)
{
Idictionary firstdict = NULL;
Bool hasdata = false;
Foreach (idictionary currentdict in List)
{
Hasdata = true;
Firstdict = currentdict;
Break;
}
If (! Hasdata)
{
Return new object [] {};
}
If (firstdict = NULL)
{
Throw new argumentexception ("idictionary entry cannot be null ");
}

String typesigniture = gettypesigniture (firstdict );

Type objecttype = gettypebytypesigniture (typesigniture );

If (objecttype = NULL)
{
Typebuilder TB = gettypebuilder (typesigniture );

Constructorbuilder constructor =
TB. definedefaconconstructor (
Methodattributes. Public |
Methodattributes. specialname |
Methodattributes. rtspecialname );

Foreach (dictionaryentry pair in firstdict)
{
Createproperty (TB,
Convert. tostring (pair. Key ),
Getvaluetype (pair. Value ));
}
Objecttype = Tb. createtype ();

_ Typebysigniture. Add (typesigniture, objecttype );
}

Return generateenumerable (objecttype, list, firstdict );
}

Private Static type gettypebytypesigniture (string typesigniture)
{
Type type;
Return _ typebysigniture. trygetvalue (typesigniture, out type )? Type: NULL;
}

Private Static type getvaluetype (object value)
{
Return Value = NULL? Typeof (object): value. GetType ();
}

Private Static string gettypesigniture (idictionary firstdict)
{
Stringbuilder sb = new stringbuilder ();
Foreach (dictionaryentry pair in firstdict)
{
SB. appendformat ("_ {0 }_{ 1}", pair. Key, getvaluetype (pair. Value ));
}
Return sb. tostring (). gethashcode (). tostring (). Replace ("-", "minus ");
}

Private Static ienumerable generateenumerable (
Type objecttype, ienumerable <idictionary> list, idictionary firstdict)
{
VaR listtype = typeof (list <>). makegenerictype (new [] {objecttype });
VaR listofcustom = activator. createinstance (listtype );

Foreach (VAR currentdict in List)
{
If (currentdict = NULL)
{
Throw new argumentexception ("idictionary entry cannot be null ");
}
VaR ROW = activator. createinstance (objecttype );
Foreach (dictionaryentry pair in firstdict)
{
If (currentdict. Contains (pair. Key ))
{
Propertyinfo property =
Objecttype. getproperty (convert. tostring (pair. Key ));
Property. setvalue (
Row,
Convert. changetype (
Currentdict [pair. Key],
Property. propertytype,
Null ),
Null );
}
}
Listtype. getmethod ("add"). Invoke (listofcustom, new [] {row });
}
Return listofcustom as ienumerable;
}

Private Static typebuilder gettypebuilder (string typesigniture)
{
Assemblyname an = new assemblyname ("tempassembly" + typesigniture );
Assemblybuilder =
Appdomain. currentdomain. definedynamicassembly (
An, assemblybuilderaccess. Run );
Modulebuilder = assemblybuilder. definedynamicmodule ("mainmodule ");

Typebuilder TB = modulebuilder. definetype ("temptype" + typesigniture
, Typeattributes. Public |
Typeattributes. Class |
Typeattributes. autoclass |
Typeattributes. ansiclass |
Typeattributes. beforefieldinit |
Typeattributes. autolayout
, Typeof (object ));
Return TB;
}

Private Static void createproperty (
Typebuilder TB, string propertyname, type propertytype)
{
Fieldbuilder = Tb. definefield ("_" + propertyname,
Propertytype,
Fieldattributes. Private );

Propertybuilder =
TB. defineproperty (
Propertyname, propertyattributes. hasdefault, propertytype, null );
Methodbuilder getpropmthdbldr =
TB. definemethod ("Get _" + propertyname,
Methodattributes. Public |
Methodattributes. specialname |
Methodattributes. hidebysig,
Propertytype, type. emptytypes );

Ilgenerator getil = getpropmthdbldr. getilgenerator ();

Getil. emit (Opcodes. ldarg_0 );
Getil. emit (Opcodes. lddes, fieldbuilder );
Getil. emit (Opcodes. Ret );

Methodbuilder setpropmthdbldr =
TB. definemethod ("SET _" + propertyname,
Methodattributes. Public |
Methodattributes. specialname |
Methodattributes. hidebysig,
Null, new type [] {propertytype });

Ilgenerator setil = setpropmthdbldr. getilgenerator ();

Setil. emit (Opcodes. ldarg_0 );
Setil. emit (Opcodes. ldarg_1 );
Setil. emit (Opcodes. stdes, fieldbuilder );
Setil. emit (Opcodes. Ret );

Propertybuilder. setgetmethod (getpropmthdbldr );
Propertybuilder. setsetmethod (setpropmthdbldr );
}
}

 

It can change the monitoring factor and region array to view the interface effect without considering the performance of large data volumes. It is purely a test code.

Note:

To reduce the file size during Silverlight running, most non-generic Collection types will not be supported. These non-generic set types are mainly those that were once considered as the essence of. NET programming, such as arraylist, hashtable, and comparer.
According to INBAR Gazit, a member of Microsoft's Basic Library Team, non-generic collections will not be released along with Silverlight 1.1. This means that although you can still use these types in major. net distributions, they cannot be used to access the Silverlight program. Affected classes include:
Arraylist
Bitarray
Caseinsensitivecomparer
Caseinsensitivehashcodeprovider
Collectionbase
Comparer
Compatiblecomparer
Dictionarybase
Emptyreadonlydictionaryinternal
Hashtable
Ihashcodeprovider
Keyvaluepairs
Listdictionaryinternal
Queue
Readonlycollectionbase
Sortedlist
Stack
In order not to be too confused, in the main. net release version, Microsoft does not intend to clear these classes or mark them as obsolete (obsolete ).
To support scenarios that do not need to know the type like data binding, some non-generic interfaces in Silverlight will still be retained:

Ienumerator
Ienumerable
Icollection
Icomparer
Idictionary
Idictionaryenumerator
Dictionaryentry
Iequalitycomparer
Ilist
Some generic collections will not be supported by Silverlight any more. INBAR explains:
Three generics are also removed from Silverlight, including queue, stack, and consumer list. This is not because they are non-generic, but because we think they are not part of the essential type that Silverlight should provide. Remember, Silverlight is a very small download. It should only include the minimum set of Apis useful for development. It is very easy to use list to implement queue and stack, and sort list is just a different implementation with a list with different performance characteristics, so these are not the essential part of our core set group.
INBAR also published an article on why generic collections should be used in traditional. NET programming, and gave some suggestions on how to change the existing code library. View Original English text

Silverlight to not support arraylist

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.