如何以编程方式在模板字段中双向绑定文本框

发布于 2024-08-20 07:30:46 字数 1252 浏览 6 评论 0 原文

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

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

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

感谢大家抽出时间

I have a gridview to which I'm adding template fields programmatically. Each of the template fields have a textbox. I would like to make this text box have 2-way binding to a database column. Please see below code.

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

}

I'm calling the above class as follows

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

How can I make the text box such that when I edit the text, this change is reflected in the database as well?

Thanks for your time everyone

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

Bonjour°[大白 2024-08-27 07:30:46

也许您可以将行 t.Text = DataBinder.Eval(dv.DataItem, columnName).ToString(); 更改为类似 t.Text= string.Format("<% # Bind(\"{0}\") %>", columnName); ?

这只是一个猜测...

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

2005 年左右 CodeProject 上的文章

程序员天堂的文章

希望这些选项之一会有用。

Perhaps you could changed the line t.Text = DataBinder.Eval(dv.DataItem, columnName).ToString(); to something like t.Text= string.Format("<%# Bind(\"{0}\") %>", columnName); ?

This is just a guess...

If that doesn't work, I found some articles that actually write new classes for handling two way databinding:

Article at CodeProject circa 2005

Article at Programmer's Heaven

Hopefully one of these options will be useful.

染年凉城似染瑾 2024-08-27 07:30:46

当然,在您看过一次之后,以编程方式执行模板字段实际上并不算太糟糕。以下是我们的做法(精简版):

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,从中提取字典,然后从中提取值,将它们添加到它自己的字典中,最终变成上传的字典数据。这就是为什么您从 Binding 委托返回 OrderedDictionary 的原因。希望有帮助!

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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文