실망스럽고 직접적인 경로를 취했습니다. 이보다 더 좋은 해결책이 없다면 마이크로 소프트는이 일에 정말로 열악한 업무를 수행했다.
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
}
어쩌면 이것이 도움이 될지 모른다. [정의 필터] [1] http://stackoverflow.com/questions/3612777/asp-net-dynamic-data-textsearch-custom-filter-template [1]에 http : // 유래. co.kr/questions/3612777/asp-net-dynamic-data-textsearch-custom-filter-template – GermanSniper