【问题标题】:Dynamically Created Textboxes not updating动态创建的文本框不更新
【发布时间】:2011-04-05 07:45:45
【问题描述】:

我在 Page_Load 事件中创建文本框并为其赋值,但是每当我加载详细信息时,我都会得到相同的输出。即使在随后的搜索中,我似乎总是得到我得到的第一个输出。

这是我的代码缺少不相关信息:

Textbox txtName = New Textbox();
protected void Page_Load(object sender, EventArgs e)
{
    LoadData();
}

void LoadData()
{
    txtName.Text = DropDownList.SelectedValue;
    tableCell.Controls.Add(txtName);
}

如果DropDownList 有两个值(例如“Item 1”和“Item 2”)并启用了自动回发,第一次它将生成并在文本框中显示“Item 1”(DropDownList 的默认值),但是如果这被改变并且自动回发被触发,文本框不会改变。

我已经尝试通过创建一个新的 TextBox 来解决这个问题,覆盖“LoadPostData”函数以防止加载它,这解决了那里的问题,但之后我无法查看数据。

知道如何解决这个问题吗?我可能以错误的方式处理这个问题。

编辑:我在DropDownList 中添加了另一个删除TextBox 的项目,以便可以再次重新创建它。删除后重新创建时,它似乎显示了正确的数据,但如果我只是尝试编辑它,则更新不正确。

Edit2:以下是此页面的其余代码,以防万一。我遇到问题的对象是 SBUName 和 SBUComments,它们都是文本框。 SBUClientDropdown 也发生了同样的问题,但我相信解决方案会相似:

DBHandler DBHandler = new DBHandler();
List<string> clients = new List<string>();
List<string> clientGroups = new List<string>();
List<string> sbus = new List<string>();

// Objects for SBU changes
string previousSBU = "";
string previousSBUClient = "";
TextBox SBUName = new TextBox() { ID = "SBUName" };
TextBox SBUComments = new TextBox() { ID = "SBUComments" };
DropDownList SBUClientDropdown = new DropDownList();

protected void Page_Load(object sender, EventArgs e)
{
    clients = DBHandler.GetClients();
    clientGroups = DBHandler.GetClientGroups();

    if (!Page.IsPostBack)
    {
        foreach (string client in clients)
        {
            SBUClientList.Items.Add(GenerateItem(client));
            ClientList.Items.Add(GenerateItem(client));
        }

        foreach (string clientGroup in clientGroups)
            ClientGroupList.Items.Add(GenerateItem(clientGroup));
    }

    if ((SBUClientList.SelectedValue.ToString() != previousSBUClient) || (SBUList.SelectedValue.ToString() != previousSBU))
    {
        previousSBUClient = SBUClientList.SelectedValue.ToString();
        previousSBU = SBUList.SelectedValue.ToString();

        sbus = DBHandler.GetSBUs(SBUClientList.SelectedValue);
        SBUList.Items.Clear();
        foreach (string sbu in sbus)
            SBUList.Items.Add(GenerateItem(sbu));

        LoadSBU();
    }
}

void LoadSBU()
{
    if ((SBUClientList.SelectedValue.Trim().Length > 0) && (SBUList.SelectedValue.Trim().Length > 0))
    {
        Entity thisSBU = DBHandler.GetSBUInformation(SBUClientList.SelectedValue, SBUList.SelectedValue);

        SBUTable.Rows.Add(GenerateHeaderRow("Client Name", "SBU Name", "Comments"));

        SBUClientDropdown.Items.Clear();
        foreach (string client in clients)
            SBUClientDropdown.Items.Add(GenerateItem(client));
        SBUClientDropdown.SelectedValue = SBUClientList.SelectedValue;
        SBUClientDropdown.SelectedIndex = SBUClientList.SelectedIndex;
        TableCell SBUClientCell = new TableCell();
        SBUClientCell.Controls.Add(SBUClientDropdown);


        SBUName.Text = thisSBU.sSBUName;
        TableCell SBUNameCell = new TableCell();
        SBUNameCell.Controls.Add(SBUName);


        SBUComments.Text = thisSBU.sSBUComments;
        TableCell SBUCommentsCell = new TableCell();
        SBUCommentsCell.Controls.Add(SBUComments);

        SBUTable.Rows.Add(GenerateRow(SBUClientCell, SBUNameCell, SBUCommentsCell));

        Button SBUSaveButton = new Button();
        SBUSaveButton.Click += new EventHandler(this.SBUSaveChanges);
        SBUSaveButton.Text = "Save SBU Changes";
        TableCell SBUButtonCell = new TableCell();
        SBUButtonCell.Controls.Add(SBUSaveButton);
        SBUButtonCell.ColumnSpan = 3;
        TableRow SBUFooter = GenerateRow(SBUButtonCell);
        SBUFooter.TableSection = TableRowSection.TableFooter;
        SBUTable.Rows.Add(SBUFooter);
    }
}

void ShowMessage(string message)
{
    OutputString.Text = "<div class=\"message\">" + message + "</div>";
}

ListItem GenerateItem(string input)
{
    ListItem output = new ListItem();
    output.Text = input;
    return output;
}

TableCell GenerateCell(string text)
{
    TableCell output = new TableCell();
    output.Text = text;
    return output;
}

TableRow GenerateRow(params TableCell[] cells)
{
    TableRow output = new TableRow();
    foreach (TableCell cell in cells)
        output.Cells.Add(cell);
    return output;
}

TableRow GenerateHeaderRow(params string[] columns)
{
    TableRow output = new TableRow();
    output.TableSection = TableRowSection.TableHeader;

    foreach (string column in columns)
    {
        TableCell thisCell = new TableCell();
        thisCell.Text = column;
        output.Cells.Add(thisCell);
    }

    return output;
}

【问题讨论】:

  • txtName 是如何呈现到页面的?你永远不会将它添加到页面中,它只存在于内存中并且永远不会呈现。
  • tableCell 是已经在页面上的 Table 中的 TableCell(此 Table 正确呈现,并且此 TextBox 正确添加到 TableCell 此处,即使其中的数据未正确显示)

标签: c# asp.net


【解决方案1】:

previousSBUClient 和 previousSBU 在每次回帖时总是空白,那么为什么要在 Page_Load 上与它们进行比较?如果您希望在回发之间保存它们的值,则需要将它们保存在 ViewState 中,我建议使用如下代码:

public string PreviousSBU
{
    get { return Convert.ToString(ViewState["PreviousSBU"] ?? string.Empty); }
    set { ViewState["PreviousSBU"] = value; }
}

可能是因为您在表格中添加了多个标题行,并且只显示了第一个到第二个之间的内容?添加后的任何标题行不显示?

在每次回发时,您都会添加一个新的标题行。但是 TextBox 是在每次回发时创建的,并且不会在其间保存,所以如果是这种情况,您根本不会看到任何内容。

【讨论】:

  • 感谢您指出 ViewState,我没有意识到这一点。关于多个标题行,我尝试添加SBUTable.Rows.Clear();,但不幸的是,同样的情况似乎仍然发生。烦人的是,我不能投票给你,因为我还没有代表,否则我会的,对此感到抱歉。
  • 很高兴为 ViewState 提供帮助。为了帮助澄清问题,我建议一个新的测试页面,它不访问数据库或有任何特殊情况,只是一个按钮,当你点击时添加一行和文本框,但使用硬编码值,看看有没有用。
  • 或者您可以使用网格完全不同,因为网格具有从数据库填充的大量行。网格本质上是 html 表格,可以根据需要动态创建行。
  • 感谢您的建议,我将尝试这两种方法,看看效果如何,非常感谢您的帮助。
【解决方案2】:

要将 txtName 呈现到页面,您应该具有以下内容:

this.Controls.Add(txtName); 在页面某处,最好在 Page_Init 中,尽管对于您列出的内容,至少在 Page_Load 中的 LoadData() 调用之前。

【讨论】:

  • 感谢您指出这一点 - 我正在这样做,但我忘记将其添加到上面的代码中,我会更新它
【解决方案3】:

猜测丢失的代码,但您是否对下拉列表进行数据绑定?如果您是,您可能每次都这样做,而不仅仅是在页面不是回发时。就像我说的,猜测你的问题不是什么,但你可能想考虑这样的事情:

if (!Page.IsPostback)
{
  MyDropDownList.DataSource = blah;
  MyDropDownList.DataBind();
}

myTextBox.Text = MyDropDownList.SelectedValue;

【讨论】:

  • 如果我在 Debug 中使用 LoadData() 中的断点运行它,它似乎在那里具有正确的值,只是当它在页面上呈现时它是不正确的。不确定这是否会有所帮助
【解决方案4】:

在 OnInit 事件中创建您的控件,因为视图状态序列化发生在 oninit 和 onload 之间。还要检查它是否是回发,以避免覆盖视图状态中的值。

【讨论】:

  • 我试过这个:protected override void OnInit(EventArgs e) { base.OnInit(e); txtName = new TextBox(); } 但同样的事情正在发生。如果我使用断点来查看那里的值,这些值似乎是正确的,这似乎是 txtName 对象的渲染问题。
【解决方案5】:

我记得如果你不向文本框提供 ID 会发生奇怪的事情,你这样做吗?

txtName.ID="txtName";`

【讨论】:

  • 不幸的是,我刚刚尝试过,但仍然没有运气。我尝试按照您所说的方式设置 ID,也像这样:TextBox txtName = new TextBox() { ID = "txtName" }; 但似乎都没有帮助
  • 好的,如果没有看到您的实际代码,我想我无法进一步帮助您。
  • 我将添加此页面中的所有代码,看看是否有帮助,请稍等
猜你喜欢
  • 2012-12-28
  • 1970-01-01
  • 2020-09-02
  • 2012-11-25
  • 1970-01-01
  • 2012-03-18
  • 2013-03-14
  • 2013-09-27
  • 1970-01-01
相关资源
最近更新 更多