2

我有一个网格视图,我正在以编程方式向其中添加模板字段。每个模板字段都有一个文本框。我想让这个文本框有 2 向绑定到数据库列。请看下面的代码。

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);

如何制作文本框,以便在编辑文本时,此更改也反映在数据库中?

谢谢大家的时间

4

2 回答 2

0

It's actually not too bad to do template fields programatically, after you've seen it once, of course. Here's how we do it, abridged:

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;
});

So here's what's going on. We use CompiledBindableTemplateBuilder and CompiledTemplateBuilder to actually build our template field's contents. Using a delegate is just an easy way to set this up.

The key to answering your question is in the second argument to the CompiledBindableTemplateBuilder, which is a delegate establishing the binding. After an edit, during submit, the template field will call ExtractValuesFromCell and recover an IBindableTemplate, from which it will extract a Dictionary and then pull the value(s) out of it, adding them to it's own dictionary which eventually gets turned into the uploaded data. So that's why you return an OrderedDictionary from the Binding delegate. Hope that helps!

于 2010-03-24T15:17:32.070 回答
0

也许你可以把这条线改成类似的t.Text = DataBinder.Eval(dv.DataItem, columnName).ToString();东西t.Text= string.Format("<%# Bind(\"{0}\") %>", columnName);

这只是猜测...

如果这不起作用,我发现一些文章实际上编写了用于处理两种方式数据绑定的新类:

大约 2005 年在 CodeProject 上的文章

程序员天堂的文章

希望这些选项之一将是有用的。

于 2010-02-06T22:53:38.300 回答