На самом деле не так уж и плохо делать поля шаблона программно, конечно, после того, как вы его видели один раз. Вот как мы это делаем, сокращенно:
TemplateField tf = new TemplateField();
//Do some config like headertext, style, etc;
tf.ItemTemplate = new CompiledTemplateBuilder(delegate(Control container)
{
//Add the regular row here, probably use a Label or Literal to show content
Label label = new Label();
lable.DataBinding += delegate(object sender, EventArgs e)
{
label.Text = ((MyDataType)DataBinder.GetDataItem(label.BindingContainer)).MyLabelDataField;
};
});
tf.EditItemTemplate = new CompiledBindableTemplateBuilder(delegate(Control container)
{
//Here we do the edit row. A CompiledBindableTemplateBuilder lets us bind in both directions
TextBox text = new TextBox();
text.DataBound += delegate(object sender, EventArgs e)
{
text.Text = ((MyDataType)DataBinder.GetDataItem(text.BindingContainer)).MyLabelDataField;
}
},
delegate(Control container)
{
OrderedDictionary dict = new OrderedDictionary();
dict["myLabelDataColumn"] = ((TextBox)container.FindControl(text.ID)).Text;
return dict;
});
Так вот что происходит. Мы используем CompiledBindableTemplateBuilder и CompiledTemplateBuilder для фактического построения содержимого поля нашего шаблона. Использование делегата - это простой способ установить это.
Ключ к ответу на ваш вопрос находится во втором аргументе CompiledBindableTemplateBuilder, который является делегатом, устанавливающим привязку. После редактирования во время отправки поле шаблона вызовет ExtractValuesFromCell и восстановит IBindableTemplate, из которого он извлечет словарь, а затем извлекает из него значения, добавляя их в свой собственный словарь, который в конечном итоге превращается в загруженный. данные. Вот почему вы возвращаете OrderedDictionary из делегата Binding. Надеюсь, это поможет!