2012-04-25 13 views
3

こんにちは、XElementとDynamicLinqを使用して汎用/動的クラスのリストを作成して、dataGridView1.DataSourceに表示しようとしていますC#ランタイムでXElementを使用してダイナミックLinqでカスタム(ダイナミック)クラスを作成する方法

まず、XElementクラスを使用してxmlを作成します。

// a List of String that are going to be our dynamic class's properties. 
List<string> elements = new List<string>(); 
elements.Add("Name"); 
elements.Add("Address"); 
elements.Add("OtherElements1"); 
elements.Add("OtherElements2"); 
elements.Add("OtherElements3"); 

// XML Root Element 
XElement XElement_Root = new XElement("Root"); 
// Item Element, This is our dynamic class 
XElement XElement_Item = new XElement("Item"); 

// Insert the elements as XElements in the Item XElement 
// This is like defining our Properties to our Item Class 
foreach (String element in elements) 
{ 
    XElement_Item.Add(new XElement(element)); 
} 

// Add 5 "Item" classes to the List "Root" 
for (int cc = 0; cc < 5; cc++) 
{ 
    foreach (String elementName in elements) 
    { 
     // Adding a Random 10 length string to each "Item" Element(property) 
     XElement_Item.Element(elementName).Value = RandomString(10); 
    } 
    // Adding the populated "Class"(Item) to the "List<>"(Root) 
    XElement_Root.Add(new XElement(XElement_Item)); 
} 

// Preview of the created xml. 
String xml = XElement_Root.ToString(); 

これは次のようになります。

- Root - 
    - Item - 
    - Name - KJHLRGOUDM - /Name - 
    - Address - QEOARCIIHO - /Address - 
    - OtherElements1 - LYHNXEPZCU - /OtherElements1 - 
    - OtherElements2 - MNSHTNYVXY - /OtherElements2 - 
    - OtherElements3 - DETZKZPJCE - /OtherElements3 - 
    - /Item - 
    - Item - 
    - Name - HYCNPMBTON - /Name - 
    - Address - QOSIADMHGE - /Address - 
    - OtherElements1 - ENLIKGEICX - /OtherElements1 - 
    - OtherElements2 - OGXYNOKFRH - /OtherElements2 - 
    - OtherElements3 - LEGJIPMKZH - /OtherElements3 - 
    - /Item - 
    ... 
- /Root - 

これはすべて良好です。しかし今私は私の問題になる 私は、このXMLをクラス "Item"のリストに入れて、dataGridView1.DataSourceに追加したい。

これは機能しますが、汎用/動的ではありません。

// Normal Linq !!! NOT GENERIC/DYNAMIC !!! 
var listOfClassItem = 
    from classItem in XElement_Root.Descendants("Item") // "Item" is our class Name 
    select new 
    { 
     Name = classItem.Element("Name").Value, 
     Address = classItem.Element("Address").Value + " " + 
      classItem.Element("OtherElements1").Value, 
     PropertyZ = classItem.Element("OtherElements3").Value 
    }; 

// populate the dataGridView1.DataSource with the New List of Class Item 
dataGridView1.DataSource = listOfClassItem.ToList(); 

グリッドは次のようになります。申し訳ありませんが何の画像、作業ブロックeveryting :(

============================================================= 
| Name   | Address     | PropertyZ  | 
============================================================= 
| SCTGCITLTN | NKMGDIYTGP LUCGNJCUNQ | DYJJJGPZDH | 
| KBMZTYAMTS | FZXDYVFAJO KVIMMNKSWG | OLKTODAGLO | 
| APQPXOSANG | NHQMYCIRWL QBHKZYKPXI | UERMLHVXVL | 
| UIJZXZIFPY | DDCESJZHHT PHHERLJUZS | WHMKNQCMUB | 
| INPBWNBEIM | QNGXVQKQRO NRXBXIUWRB | DQAYPIBOPX | 
============================================================= 

OKので、これは私がこのだっしようとしたものを、 いいがジェネリックではない/ダイナミックではありません。

// Dynamic Linq now this should be more GENERIC/DYNAMIC 
// I want the User to be able to select which fields (properties) they want to show in the DataGrid 
String selectQuery = GetSelectedFields(); // private String GetSelectedFields() { return ...} 
// selectQuery will then be some thing like. 
selectQuery = " new (Element(\"Name\").Value as Name, " + 
    " Element(\"Address\").Value + \" \" + Element(\"OtherElements1\").Value as Address, " + 
    " Element(\"OtherElements3\").Value as PropertyZ)"; 

// Then using Dynamic Linq to get the generic/dynamic class from the selection. 
// !!! THIS IS WHERE I'M STUCK !!! this does not work. :(
var listOfClassItem2 = XElement_Root.Descendants("Item").AsQueryable().Select(selectQuery); 

// I Found that this was the easiest way to get the "var" back to a List, to add to the .DataSource 
// because the IQueryable above does not have a .ToList(); 
List<object> ListOfItem = new List<object>(); 
foreach (var varItem in listOfClassItem2) 
{ 
    ListOfItem.Add(varItem); 
} 

// populate the dataGridView1.DataSource with the New List of Class Dynamic Item 
dataGridView1.DataSource = ListOfItem; 

私は、次のエラーメッセージが表示されます。

No applicable method 'Element' exists in type 'XElement' 

誰かが、私を助けてくださいすることができます

XElement_Root.Descendants("Item").AsQueryable().Select(selectQuery); 

私はNormal Linqを使用したときと同じ結果を得ることができます。 Thx。

答えて

4

私は自分の問題を解決しました。 残念ながら、XElementを使用するのは最良の選択ではありませんでした。

この記事を読んだ後、私は新しいアイデアを得ました。

How do I create dynamic properties in C#? - Answered by Paolo Tedesco

まず魔法のための動的クラス

// This is the class we are going to add to a List 
public class DynamicClass 
{ 
    // property is a class that will create dynamic properties at runtime 
    private DynamicProperty _property = new DynamicProperty(); 

    public DynamicProperty property 
    { 
     get { return _property; } 
     set { _property = value; } 
    } 
} 

public class DynamicProperty 
{ 
    // a Dictionary that hold all the dynamic property values 
    private Dictionary<string, object> properties = new Dictionary<string, object>(); 

    // the property call to get any dynamic property in our Dictionary, or "" if none found. 
    public object this[string name] 
    { 
     get 
     { 
      if (properties.ContainsKey(name)) 
      { 
       return properties[name]; 
      } 
      return ""; 
     } 
     set 
     { 
      properties[name] = value; 
     } 
    } 
} 

とノウのためのバックボーンを作成することができます。

// create a List of String that are going to be our dynamic class's properties. 
List<string> PropertyNames = new List<string>(); 
PropertyNames.Add("Name"); 
PropertyNames.Add("Age"); 
PropertyNames.Add("Phone"); 
PropertyNames.Add("Address"); 
PropertyNames.Add("City"); 

// Make a list of the DynamicClass 
List<DynamicClass> DynamicClassList = new List<DynamicClass>(); 

// Adding 5 DynamicClass classes to the DynamicClassList 
for (int cc = 0; cc < 5; cc++) 
{ 
    // declare a new DynamicClass 
    var dynamicClass = new DynamicClass(); 

    // Give Random values to the New Properties. 
    // (because dynamicClass.property["xxx"] is of type object it could be anything.) 
    // I'm just going to use random strings. 
    foreach (String PropertyName in PropertyNames) 
    { 
     dynamicClass.property[PropertyName] = RandomString(5 + cc); // private string RandomString(int size) 
    } 

    // It could also have looked something like this. 

    // dynamicClass.property["Name"] = "Peter"; 
    // dynamicClass.property["Age"] = 25; 
    // .... 

    // Add the populated class to the list. 
    DynamicClassList.Add(dynamicClass); 
} 

// Again I want the User to be able to select which fields (properties) they want to show in the DataGrid. 
String selectQuery = GetSelectedFields(); // private string GetSelectedFields() { return ... } 
// selectQuery will then be something like. 
selectQuery = "new (property[\"Name\"] as Name, " + 
    " property[\"Age\"] as Age, " + 
    " property[\"Phone\"] as Phone, " + 
    " property[\"Address\"] + \" \" + property[\"City\"] as Address)"; 

// Make a new DynamicClass that only contains the fields the user wants to see. 
var newDynamicClasses = DynamicClassList.AsQueryable().Select(selectQuery); 

// I Found that this was the easiest way to get the "var" back to a List, to add to the .DataSource 
// because the IQueryable above does not have a .ToList(); 
List<object> newDynamicClassList = new List<object>(); 
foreach (var varDynamicClass in newDynamicClasses) 
{ 
    newDynamicClassList.Add(varDynamicClass); 
} 

// populate the dataGridView1.DataSource with the New List of DynamicClass 
dataGridView1.DataSource = newDynamicClassList; 

これはそれです。

もう一度パオロと私はこれが他の誰かを助けることを願っています。

関連する問題