#c# #asp.net #data-binding
#c# #asp.net #привязка к данным
Вопрос:
Сначала исходный код:
Default.aspx:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication2.Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Repeater ID="Bars" runat="server">
<ItemTemplate>
<div>
<asp:TextBox ID="Name" Text='<%# Eval("Name") %>' runat="server" AutoPostBack="true" />
<asp:TextBox ID="Description" Text='<%# Eval("Description") %>' runat="server" AutoPostBack="true" />
</div>
</ItemTemplate>
</asp:Repeater>
<asp:Button ID="AddBar" Text="Add Bar" runat="server" onclick="AddBar_Click" />
</div>
</form>
</body>
</html>
Default.aspx.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication2
{
public class Foo
{
public string Widget { get; set; }
public string Cog { get; set; }
public List<Bar> Bars { get; set; }
}
public class Bar
{
public string Name { get; set; }
public string Description { get; set; }
}
public partial class Default : System.Web.UI.Page
{
public Foo Foo
{
get
{
var retval = Session["Foo"];
if (retval == null)
{
retval = new Foo();
Session["Foo"] = retval;
}
return retval == null ? new Foo() : (Foo)retval;
}
set
{
Session["Foo"] = value;
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
var f = new Foo() { Bars = new List<Bar>(), Cog = "Cog one", Widget = "Widget Master" };
f.Bars.Add(new Bar() { Name = "Bar one", Description = "hello." });
Foo = f;
Bind();
}
}
protected void Bars_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item != null amp;amp; e.Item.DataItem != null)
{
var b = e.Item.DataItem as Bar;
var Name = e.Item.FindControl("Name") as TextBox;
var Description = e.Item.FindControl("Description") as TextBox;
Name.TextChanged = new EventHandler(Name_TextChanged);
}
}
protected void Name_TextChanged(object sender, EventArgs e)
{
var Name = sender as TextBox;
var listItem = Name.Parent as RepeaterItem;
var f = Foo;
var b = f.Bars[listItem.ItemIndex];
b.Name = Name.Text;
Foo = f;
Bind();
}
protected void AddBar_Click(object sender, EventArgs e)
{
var f = Foo;
f.Bars.Add(new Bar());
Foo = f;
Bind();
}
private void Bind()
{
Bars.ItemDataBound = new RepeaterItemEventHandler(Bars_ItemDataBound);
Bars.DataSource = Foo.Bars;
Bars.DataBind();
}
}
}
Итак, я годами не использовал привязку к данным, но я подумал, что освежу свою память, но я не могу заставить это работать. Когда я запускаю приложение, я вижу одну запись со значениями, которые я ожидаю. Если я нажимаю добавить, отображаются новые значения, а существующее значение сохраняется.
Вот в чем проблема: когда я меняю значение в текстовом поле Name, я вижу обновление страницы, но мое событие Name_TextChanged не прерывается. Поскольку это не срабатывает, значение возвращается к тому, что было раньше.
Комментарии:
1. Ваш обработчик событий
void Name_TextChanged
является частным. сделайте это защищенным и посмотрите, работает ли это сейчас?2. Не повезло. Обновил вопрос, чтобы он соответствовал.
3. Я вижу в запросе, что новые значения также отправляются на сервер.
4. MSDN ясно показывает, что элементы управления asp могут содержаться в шаблоне: msdn.microsoft.com/en-us/library/x8f2zez5.aspx
5. Что ж. Я вижу, вы повторно привязываете в
AddBar_Click
. Привязка данных должна быть выполнена один раз, я думаю, когда не в обратной передаче (что вы делаете правильно в Page_Load)
Ответ №1:
Прикрепите событие onTextChanged в aspx. Работают следующие коды.
protected void Bars_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item != null amp;amp; e.Item.DataItem != null)
{
var b = e.Item.DataItem as Bar;
var Name = e.Item.FindControl("Name") as TextBox;
var Description = e.Item.FindControl("Description") as TextBox;
// Commented
// Name.TextChanged = new EventHandler(Name_TextChanged);
}
}
<asp:TextBox ID="Name" Text='<%# Eval("Name") %>' runat="server"
AutoPostBack="true" OnTextChanged="Name_TextChanged" />
<asp:TextBox ID="Description" Text='<%# Eval("Description") %>'
runat="server" AutoPostBack="true" OnTextChanged="Name_TextChanged" />
Комментарии:
1. Ну, я думаю, я сделал это более сложным, чем это должно было быть. Спасибо @Win
2. ЕСЛИ у кого-нибудь есть ссылка на это, это тоже было бы здорово.