2012-06-20 10 views
9

मैं कुछ निर्दिष्ट पैरामीटर से एक HTML तालिका जेनरेट करना चाहता हूं। विशेष रूप से, दो पैरामीटर मैं अपने विधि में पारित करना चाहते हैं: IEnumerable सूची, और उदाहरण के लिए टी के गुणों में से कुछ सबसेट, मान लीजिए कि मैं इस वर्ग की एक सूची है करते हैं:निर्दिष्ट गुणों के साथ जेनेरिक क्लास की सूची से HTML तालिका जेनरेट करें

class Person 
{ 
    string FirstName 
    string MiddleName 
    string LastName 
} 

मान लीजिए कि सूची है चलो इसमें 5 लोग मैं वहाँ जो गुण मैं उत्पन्न तालिका चाहते हैं निर्दिष्ट करने के लिए एक बेहतर तरीका है यकीन है कि

List<Person> people; 
...add people to list 

string HTML = GetMyTable(people, "FirstName", "LastName"); 

: मैं कुछ इस तरह करने से उस वर्ग के एक HTML तालिका (या किसी अन्य मनमाना वर्ग) प्राप्त करने में सक्षम होना चाहता हूँ से (या कौन से गुण मैं तालिका से बाहर रखना चाहते हैं, यह बेहतर होगा क्योंकि मैं आमतौर पर अधिकतर या सभी वर्ग की संपत्तियों को चाहता हूं), लेकिन मुझे यकीन नहीं है कि मैंने कभी प्रतिबिंब का उपयोग नहीं किया है, लेकिन मैं यह अनुमान लगा रहा है कि कैसे)। साथ ही, विधि किसी भी प्रकार की कक्षा की सूची स्वीकार करनी चाहिए।

इसे पूरा करने के तरीके पर कोई भी चालाक विचार?

उत्तर

19

शायद ऐसा कुछ हो सकता है?

var html = GetMyTable(people, x => x.LastName, x => x.FirstName); 

public static string GetMyTable<T>(IEnumerable<T> list,params Func<T,object>[] fxns) 
{ 

    StringBuilder sb = new StringBuilder(); 
    sb.Append("<TABLE>\n"); 
    foreach (var item in list) 
    { 
     sb.Append("<TR>\n"); 
     foreach(var fxn in fxns) 
     { 
      sb.Append("<TD>"); 
      sb.Append(fxn(item)); 
      sb.Append("</TD>"); 
     } 
     sb.Append("</TR>\n"); 
    } 
    sb.Append("</TABLE>"); 

    return sb.ToString(); 
} 

--Version 2.0--

public static string GetMyTable<T>(IEnumerable<T> list, params Expression<Func<T, object>>[] fxns) 
{ 

    StringBuilder sb = new StringBuilder(); 
    sb.Append("<TABLE>\n"); 

    sb.Append("<TR>\n"); 
    foreach (var fxn in fxns) 
    { 
     sb.Append("<TD>"); 
     sb.Append(GetName(fxn)); 
     sb.Append("</TD>"); 
    } 
    sb.Append("</TR> <!-- HEADER -->\n"); 


    foreach (var item in list) 
    { 
     sb.Append("<TR>\n"); 
     foreach (var fxn in fxns) 
     { 
      sb.Append("<TD>"); 
      sb.Append(fxn.Compile()(item)); 
      sb.Append("</TD>"); 
     } 
     sb.Append("</TR>\n"); 
    } 
    sb.Append("</TABLE>"); 

    return sb.ToString(); 
} 

static string GetName<T>(Expression<Func<T, object>> expr) 
{ 
    var member = expr.Body as MemberExpression; 
    if (member != null) 
     return GetName2(member); 

    var unary = expr.Body as UnaryExpression; 
    if (unary != null) 
     return GetName2((MemberExpression)unary.Operand); 

    return "?+?"; 
} 

static string GetName2(MemberExpression member) 
{ 
    var fieldInfo = member.Member as FieldInfo; 
    if (fieldInfo != null) 
    { 
     var d = fieldInfo.GetCustomAttribute(typeof(DescriptionAttribute)) as DescriptionAttribute; 
     if (d != null) return d.Description; 
     return fieldInfo.Name; 
    } 

    var propertInfo = member.Member as PropertyInfo; 
    if (propertInfo != null) 
    { 
     var d = propertInfo.GetCustomAttribute(typeof(DescriptionAttribute)) as DescriptionAttribute; 
     if (d != null) return d.Description; 
     return propertInfo.Name; 
    } 

    return "?-?"; 
} 

पुनश्च:fxn.Compile() कॉलिंग बार-बार एक तंग पाश में प्रदर्शन हत्यारा हो सकता है। इसे एक शब्दकोश में कैश करना बेहतर हो सकता है।

public static string GetMyTable(IEnumerable list, params string[] columns) 
{ 
    var sb = new StringBuilder(); 
    foreach (var item in list) 
    { 
     //todo this should actually make an HTML table, not just get the properties requested 
     foreach (var column in columns) 
      sb.Append(item.GetType().GetProperty(column).GetValue(item, null)); 
    } 
    return sb.ToString(); 
} 
//used like 
string HTML = GetMyTable(people, "FirstName", "LastName"); 

या इसका उपयोग करते lambdas:

public static string GetMyTable<T>(IEnumerable<T> list, params Func<T, object>[] columns) 
{ 
    var sb = new StringBuilder(); 
    foreach (var item in list) 
    { 
     //todo this should actually make an HTML table, not just get the properties requested 
     foreach (var column in columns) 
      sb.Append(column(item)); 
    } 
    return sb.ToString(); 
} 
//used like 
string HTML = GetMyTable(people, x => x.FirstName, x => x.LastName); 
lambdas के साथ

, क्या हो रहा है कि आप प्रत्येक पाने के लिए GetMyTable विधि करने के तरीकों से गुजर रहे हैं

+0

उदाहरण के लिए यदि आप int और स्ट्रिंग चुनने का प्रयास करते हैं तो क्या होता है? 'पी' 'ऑब्जेक्ट 'बन जाएगा, या यह संकलित नहीं होगा? –

+0

@TimS। धन्यवाद मैंने जवाब अपडेट किया। –

+0

क्या आप समझा सकते हैं कि "fxn (item)" क्या कर रहा है? – birdus

3

यहाँ दो दृष्टिकोण, एक का उपयोग कर प्रतिबिंब हैं संपत्ति। इसका मजबूत टाइपिंग, और शायद प्रदर्शन जैसे प्रतिबिंब पर लाभ होता है।

+0

मदद के लिए धन्यवाद, टिम। मैं ऐसा करने के कई तरीकों को देखने की सराहना करता हूं। – birdus

6

यह वही है जो मैंने किया और ऐसा लगता है कि यह ठीक काम करता है और एक बड़ा प्रदर्शन नहीं मारा जाता है।

public static string ToHtmlTable<T>(this List<T> listOfClassObjects) 
    { 
     var ret = string.Empty; 

     return listOfClassObjects == null || !listOfClassObjects.Any() 
      ? ret 
      : "<table>" + 
       listOfClassObjects.First().GetType().GetProperties().Select(p => p.Name).ToList().ToColumnHeaders() + 
       listOfClassObjects.Aggregate(ret, (current, t) => current + t.ToHtmlTableRow()) + 
       "</table>"; 
    } 

    public static string ToColumnHeaders<T>(this List<T> listOfProperties) 
    { 
     var ret = string.Empty; 

     return listOfProperties == null || !listOfProperties.Any() 
      ? ret 
      : "<tr>" + 
       listOfProperties.Aggregate(ret, 
        (current, propValue) => 
         current + 
         ("<th style='font-size: 11pt; font-weight: bold; border: 1pt solid black'>" + 
         (Convert.ToString(propValue).Length <= 100 
          ? Convert.ToString(propValue) 
          : Convert.ToString(propValue).Substring(0, 100)) + "..." + "</th>")) + 
       "</tr>"; 
    } 

    public static string ToHtmlTableRow<T>(this T classObject) 
    { 
     var ret = string.Empty; 

     return classObject == null 
      ? ret 
      : "<tr>" + 
       classObject.GetType() 
        .GetProperties() 
        .Aggregate(ret, 
         (current, prop) => 
          current + ("<td style='font-size: 11pt; font-weight: normal; border: 1pt solid black'>" + 
            (Convert.ToString(prop.GetValue(classObject, null)).Length <= 100 
             ? Convert.ToString(prop.GetValue(classObject, null)) 
             : Convert.ToString(prop.GetValue(classObject, null)).Substring(0, 100) + 
              "...") + 
            "</td>")) + "</tr>"; 
    } 

यह सिर्फ ToHtmlTable() एक सूची उदाहरण पारित का उपयोग करें:

सूची दस्तावेजों = GetMyListOfDocuments(); var table = document.ToHtmlTable();

संबंधित मुद्दे