Как двухстороннее связывание текстового поля в шаблоне полей программно - PullRequest
2 голосов
/ 06 февраля 2010

У меня есть сетка, в которую я добавляю поля шаблона программно. Каждое из полей шаблона имеет текстовое поле. Я хотел бы, чтобы это текстовое поле имело двухстороннюю привязку к столбцу базы данных. Пожалуйста, смотрите код ниже.

public class CustomEditItemTemplate : ITemplate
{
private DataControlRowType templateType;
private string columnName;

public CustomEditItemTemplate(DataControlRowType type, string colname)
{
    this.templateType = type;
    this.columnName = colname;
}

public void InstantiateIn(System.Web.UI.Control container)
{
TextBox tb = new TextBox();
tb.ID = columnName;
tb.DataBinding += new EventHandler(this.tb_DataBinding);
container.Controls.Add(tb);
}

private void tb_DataBinding(Object sender, EventArgs e)
{
    TextBox t = (TextBox)sender;
    DetailsView dv = (DetailsView)t.NamingContainer;

    //This line does only one way binding. It takes the rows from the database and displays
    //them in the textboxes. The other way binding is not done. This is why my code fails
    t.Text = DataBinder.Eval(dv.DataItem, columnName).ToString();        
}

}

Я вызываю вышеуказанный класс следующим образом

tf = new TemplateField();
tf.HeaderText = "My First Names";
tf.EditItemTemplate = new CustomEditItemTemplate(DataControlRowType.DataRow, "firstName");
dvModify.Fields.Add(tf);

Как сделать текстовое поле таким, чтобы при редактировании текста это изменение отражалось и в базе данных?

Спасибо за ваше время всем

Ответы [ 2 ]

0 голосов
/ 24 марта 2010

На самом деле не так уж и плохо делать поля шаблона программно, конечно, после того, как вы его видели один раз. Вот как мы это делаем, сокращенно:

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. Надеюсь, это поможет!

0 голосов
/ 07 февраля 2010

Возможно, вы могли бы изменить строку t.Text = DataBinder.Eval(dv.DataItem, columnName).ToString(); на что-то вроде t.Text= string.Format("<%# Bind(\"{0}\") %>", columnName);?

Это всего лишь предположение ...

Если это не сработает, я нашел несколько статей, которые на самом деле пишут новые классы для обработки двусторонней привязки данных:

Статья в CodeProject около 2005

Статья на небесах программиста

Надеюсь, один из этих вариантов будет полезен.

...