2009-12-11 7 views
6

ビュー内のスパゲッティコードを減らすために、特定のHtmlHelperテーブル拡張を作成しようとしています。オブジェクトリストからMVC HtmlHelperテーブルを作成する方法

ドメインオブジェクトのリストを取得する私は、ドメインオブジェクトのプロパティを列として使用する際に、よりインテリジェントな表を表示したいと考えています。また、いくつかのプロパティを列として表示しないようにしたいと思います。考えられるのは、プロパティを表示しないように属性を付けることです。

うまくいけば、それは理にかなっているが、私は誰もがこのアイデアのご意見/提案や任意の選択肢を持っていた場合、これまで...

public static string MyTable(this HtmlHelper helper, string name, 
    IList<MyObject> items, object tableAttributes) 
{ 
    if (items == null || items.Count == 0) 
     return String.Empty; 

    StringBuilder sb = new StringBuilder(); 
    BuildTableHeader(sb, items[0].GetType()); 

    //TODO: to be implemented... 
    //foreach (var i in items) 
    // BuildMyObjectTableRow(sb, i); 

    TagBuilder builder = new TagBuilder("table"); 
    builder.MergeAttributes(new RouteValueDictionary(tableAttributes)); 
    builder.MergeAttribute("name", name); 
    builder.InnerHtml = sb.ToString(); 

    return builder.ToString(TagRenderMode.Normal); 
} 

private static void BuildTableHeader(StringBuilder sb, Type p) 
{ 
    sb.AppendLine("<tr>"); 

    //some how here determine if this property should be shown or not 
    //this could possibly come from an attribute defined on the property   
    foreach (var property in p.GetProperties()) 
     sb.AppendFormat("<th>{0}</th>", property.Name); 

    sb.AppendLine("</tr>"); 
} 

//would be nice to do something like this below to determine what 
//should be shown in the table 
[TableBind(Include="Property1,Property2,Property3")] 
public partial class MyObject 
{ 
    ...properties are defined as Linq2Sql 
} 

だから私は思っていたようになったのはここですか?

答えて

1

約1時間の作業の後、私は自分が望むものを作り出すことができました。私の解決策は、どのプロパティがテーブルに表示されているかを指定したドメインオブジェクトクラスの属性を作成することでした。

MVC 1.0のBindAttribute属性(ソースコードを参照)に基づいて、私はTableProperty属性を作成しました。

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)] 
public class TableProperty : Attribute 
{ 
    private string m_include; 
    private string[] m_includeSplit; 

    public TableProperty() 
    { 
     m_includeSplit = new string[0]; 
    } 

    public string Include 
    { 
     get 
     { 
      return (m_include ?? string.Empty); 
     } 
     set 
     { 
      m_include = value; 
      m_includeSplit = value.Split(','); 
     } 
    } 

    public bool IsPropertyAllowed(string propertyName) 
    { 
     return IsPropertyAllowed(propertyName, m_includeSplit); 
    } 

    internal static bool IsPropertyAllowed(string propertyName, string[] includeProperties) 
    { 
     return ((includeProperties == null) || (includeProperties.Length == 0)) || includeProperties.Contains<string>(propertyName, StringComparer.OrdinalIgnoreCase); 
    } 
} 

これは私がオブジェクトのプロパティを取得し、許可リストに各プロパティを一致させるためにリフレクションを使用BuildTableHeader内すると

[TableProperty(Include="Property1,Property2,Property3")] 
public partial class MyObject 
{ ... 

...私は、この属性を持つ私のドメインオブジェクトを飾るために許可。

private static void BuildTableHeader(StringBuilder sb, Type p) 
{ 
    sb.AppendLine("<tr>"); 

    TableProperty tp = p.GetCustomAttributes(typeof(TableProperty), true)[0]; 

    foreach (var property in p.GetProperties()) 
     if (tp.IsPropertyAllowed(property.Name)) 
      sb.AppendFormat("<th>{0}</th>", property.Name); 

このソリューションは私の小さなアプリケーションではうまくいきましたが、より良い実装のためにMvcContribのグリッドをもっと見ていきます。

+0

クライアント側の柔軟性が必要な場合は、jqGridも検討してください。 – queen3

1

私は強くMvcContribのGridを使用することをお勧めします。もしそうでないと決めたら、少なくともテーブル生成インターフェースの問題をどのように解決したかを見てみることができます。

+0

グリッドへのリンクありがとうございます。私はこれを見ていきますが、当分の間私はそれを自分で実装することができました。 – David

関連する問題