2012-02-14 2 views
6

Я работаю над проектом Web Forms, который загружает результаты запросов Sql в DataTable.Динамическое привязку к пользовательскому бизнес-объекту в Runtime

Эти DataTable s передаются до интерфейса, где мы связываем их с веб-контролем Repeater.

Это прекрасно работает. Однако теперь мы хотим привязать к нашим собственным пользовательским классам вместо DataTable. К сожалению, я думал, что явный ответ не сработал (внедряя IDictionary<string, object> в наш класс).

Что нам нужно для привязки Eval к ​​Datum без создания конкретного свойства для каждого привязки? Очевидно, DataRow не должен конкретно реализовывать каждое свойство, которое мы связываем. Итак, как-то кажется, что Eval может искать значения свойств по имени в DataRow.

Вот пользовательский класс

public class Datum: IDictionary<string, object> 
{ 
    private Dictionary<string, object> _entries; 

    public Datum() 
    { 
     _entries = new Dictionary<string, object>(); 
    } 

    public object this[string s] 
    { 
     get 
     { 
      return this._entries[s]; 
     } 
    } 

    ... 
} 

Вот где DataSource устанавливается в aspx.cs файл

rptTags.DataSource = new[] { new Datum { {"Count", 1} }, new Datum { {"Count", 2 } }; 

А вот связывание в файле ASPX

<asp:Repeater ID="rptTags" runat="server"> 
    <ItemTemplate> 
     <%# (int)Eval("Count") > 
    </ItemTemplate> 
</asp:Repeater> 

Используя приведенный выше пример, мы получаем сообщение об ошибке, говорящее, что данное свойство не существует, что верно, но оно d на DataRow тоже не существует. Как это сделать, как System.Data.DataRow?

+0

Вы можете поделиться вам класс модели данных и Eval выражение, что бы облегчить помощь. –

+0

«Это делает кошмар, чтобы испытать что-нибудь». Например? –

+0

@mark Хорошо, я думаю, что получаю это ... – Aristos

ответ

1

Я пришел сегодня утром со свежими глазами и провел несколько часов, пройдя через .Net Framework с ILSpy. Наконец, я смог понять эту загадку и реализовать рабочее решение. Я перечислил все, что я узнал, которые уместны для решения, а затем подробно расскажу о моей реализации.

  • Когда вы привязываете DataTable к ретранслятору, каждый RepeaterItem не привязывается к DataRow, как я и ожидал, но к DataRowView. Это действительно не важно, за исключением того, что DataRowView реализует интерфейс ICustomTypeDescriptor, который мы должны реализовать в нашем классе.
  • Несмотря на то, что MSDN documentation говорит, что метод Eval использует отражение для выполнения позднего связывания, и ваше выражение должно оцениваться публичным свойством, это просто неверно. Оператор Eval использует метод GetProperties() для ICustomTypeDescriptor для оценки вашего выражения.

Имея это в виду, вот шаги, которые я должен был предпринять, чтобы создать свой собственный пользовательский тип, который я мог бы динамически связывать так же, как DataTable.

  1. Создайте свой собственный пользовательский класс, который наследуется от PropertyDescriptor.
  2. Реализовать все абстрактные элементы PropertyDescriptor. Для динамического связывания наиболее важным является GetValue(). Здесь вы определяете, как получить значения из класса, к которому вы привязываетесь.
  3. В классе, к которому вы привяжетесь, наследуется от CustomTypeDescriptor. Это общий класс, реализующий ICustomTypeDescriptor.
  4. Переопределите метод GetProperties() CustomTypeDescriptor и верните список ваших PropertyDescriptors (созданных на шагах 1-2) для каждого значения, с которым вы хотели бы привязываться.
  5. Убедитесь, что ваши PropertyDescriptions имеют свой собственный набор свойств. Это свойство .Net сравнивает ваше выражение Eval с тем, чтобы определить, какой PropertyDescription использовать при привязке.
  6. Установите CustomTypeDescriptor объект (созданный на шаге 3-5) в качестве источника данных о наличии WebControl и использовать Eval(), чтобы связать с ним динамически
0

Связываемый источник данных должен реализовывать либо IEnumerable, либо IListSource.

Что касается динамического аспекта: имейте в виду, что часть магии привязки данных происходит с использованием отражения.

+0

Спасибо за ответ. Да, я прочитал в документации MSDN, что он использует отражение для позднего связывания. Тем не менее, DataRow все еще может уйти с динамической привязкой данных так или иначе, поэтому я чувствую, что тоже должен быть способен. –

Смежные вопросы