2011-07-29 10 views
1

システム管理者用の単純なエンティティ管理コンソールとして、ASP.NET Dynamic Data 4.0をEF POCO ObjectContextで使用したいと考えています(この技術を放棄することを検討しています...)。ASP.NET動的データフィルタリング

私は挿入/更新作業をしています。

追加のデータ型用のフィルタを追加する方法を説明しました(組み込みのものは役に立たないため)。私はどのようにQueryableFilterRepeaterフィルタリングとして私の列を公開する方法を把握することはできません。 FilterUIHintsをすべての適用可能な型に追加することはできません。そのため、これは受け入れられる解決策ではありません。私は組み込みのEntity Frameworkメタデータモデルプロバイダを活用したいと思います。私は自分のことを書いてはいけません。この問題は、QueryableFilterIteratorがMetaTable.GetFilteredColumns()を呼び出していて、bool/int/DateTimeカラム(これは役に立たない)を返すだけであるという事実に気づいているようです。

ASP.NET動的データフィルタリング(http://dynamicdatafiltering.codeplex.com/)をチェックアウトしましたが、4.0では維持されていないようです。

私は二つの質問があると思い:

  1. をこれを行う方法は、(フィルタ可能として私の列を取得する)はありますか?
  2. ダイナミックデータは実際に現実世界で使用するのに適していますか?
+1

これはおそらくあなたを助けることができます! [カスタムフィルタ] [1] http://stackoverflow.com/questions/3612777/asp-net-dynamic-data-textsearch-custom-filter-template [1]:のhttp://のstackoverflow。 com/questions/3612777/asp-net-dynamic-data-textsearch-custom-filter-template – GermanSniper

答えて

1

不満を抱いて直接ルートをとった。これに対してもっと良い解決策がないのなら、マイクロソフトはこれで本当に貧弱な仕事をしました:

public class QueryableFilterRepeater : System.Web.DynamicData.QueryableFilterRepeater 
    { 
     private static readonly FieldInfo FiltersField = typeof(System.Web.DynamicData.QueryableFilterRepeater).GetField("_filters", BindingFlags.Instance | BindingFlags.NonPublic); 
     private static readonly FieldInfo DataSourceField = typeof(System.Web.DynamicData.QueryableFilterRepeater).GetField("_dataSource", BindingFlags.Instance | BindingFlags.NonPublic); 
     private static readonly MethodInfo FilterInitializeMethod = typeof(DynamicFilter).GetMethod("Initialize", BindingFlags.Instance | BindingFlags.NonPublic); 
     private static readonly PropertyInfo FilterContextProperty = typeof(DynamicFilter).GetProperty("Context", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly); 
     private static readonly MethodInfo PageInitCompleteMethod = typeof(System.Web.DynamicData.QueryableFilterRepeater).GetMethod("Page_InitComplete", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly); 
     private static readonly EventInfo InitCompleteEvent = typeof(Page).GetEvent("InitComplete"); 

     private readonly List<DynamicFilter> filters; 
     private int filterCount; 
     private bool initialized; 

     public IEnumerable<DynamicFilter> Filters 
     { 
      get { return filters; } 
     } 

     public QueryableFilterRepeater() 
     { 
      filters = (List<DynamicFilter>)FiltersField.GetValue(this); 
     } 

     private IQueryableDataSource DataSource 
     { 
      get { return DataSourceField.GetValue(this) as IQueryableDataSource; } 
     } 
     protected override void OnInit(EventArgs e) 
     { 
      base.OnInit(e); 

      InitCompleteEvent.RemoveEventHandler(Page, Delegate.CreateDelegate(typeof(EventHandler), this, PageInitCompleteMethod)); 

      Page.InitComplete += new EventHandler(Page_InitComplete); 
     } 

     protected override void OnLoad(EventArgs e) 
     { 
      filters.Select((f, i) => new { f, i }).Where(x => x.i > filterCount - 1).ToList().ForEach(x => filters.Remove(x.f)); 
      Controls.OfType<Control>().Select((c, i) => new { c, i }).Where(x => x.i > filterCount - 1).ToList().ForEach(x => Controls.Remove(x.c)); 
      base.OnLoad(e); 
     } 

     private void Page_InitComplete(object sender, EventArgs e) 
     { 
      if (!initialized) 
      { 
       Controls.Clear(); 
       filters.Clear(); 

       MetaTable metaTable = DataSource.GetMetaTable(); 
       int num = 0; 
       foreach (MetaColumn column in metaTable.Columns) 
       { 
        string filterUIHint = GetFilterUIHint(column); 
        if (filterUIHint == null) continue; 

        var filterRepeaterItem = new FilterRepeaterItem(); 
        filterRepeaterItem.DataItemIndex = num; 
        filterRepeaterItem.DisplayIndex = num; 
        FilterRepeaterItem container = filterRepeaterItem; 
        num++; 
        ItemTemplate.InstantiateIn(container); 
        Controls.Add(container); 
        var dynamicFilter = container.FindControl(DynamicFilterContainerId) as DynamicFilter; 
        if (dynamicFilter == null) 
        { 
         throw new InvalidOperationException(); 
        } 
        FilterContextProperty.SetValue(dynamicFilter, new HttpContextWrapper(Context), null); 
        dynamicFilter.DataField = column.Name; 
        container.DataItem = column; 
        container.DataBind(); 
        container.DataItem = null; 

        dynamicFilter.FilterUIHint = filterUIHint; 
        filters.Add(dynamicFilter); 
        filterCount++; 
       } 
       filters.ForEach(f => FilterInitializeMethod.Invoke(f, new[] { DataSource })); 
       initialized = true; 
      } 
     } 

     private string GetFilterUIHint(MetaColumn column) 
     { 
      if (GetUnderlyingType(column.ColumnType) == typeof(string)) 
      { 
       return "String"; 
      } 
      if (GetUnderlyingType(column.ColumnType) == typeof(bool)) 
      { 
       return "Boolean"; 
      } 
      if (GetUnderlyingType(column.ColumnType).IsEnum) 
      { 
       return "Enumeration"; 
      } 
      if (GetUnderlyingType(column.ColumnType) == typeof(DateTime)) 
      { 
       return "DateTime"; 
      } 
      if (column is MetaForeignKeyColumn) 
      { 
       return "ForeignKey"; 
      } 
      if (column is MetaChildrenColumn) 
      { 
       return "Children"; 
      } 

      return null; 
     } 

     private Type GetUnderlyingType(Type type) 
     { 
      return Nullable.GetUnderlyingType(type) ?? type; 
     } 

     // Nested Types 

     #region Nested type: FilterRepeaterItem 

     private class FilterRepeaterItem : Control, IDataItemContainer 
     { 
      // Properties 

      #region IDataItemContainer Members 

      public object DataItem { get; internal set; } 
      public int DataItemIndex { get; internal set; } 
      public int DisplayIndex { get; internal set; } 

      #endregion 
     } 

     #endregion 
    }