【问题标题】:Gridview edit mode won't modify textbox propertiesGridview 编辑模式不会修改文本框属性
【发布时间】:2011-07-18 19:59:45
【问题描述】:

我的 gridview 绑定到 SqlDataSource 并动态填充。我面临在编辑模式下修改文本框属性的问题。

protected void gvData_PreRender(object sender, EventArgs e)
{
    if (this.gvData.EditIndex != -1)
        for (int i = 1; i < gvData.Rows[gvData.EditIndex].Cells.Count; i++)
        {
            LinkButton lb = new LinkButton();
            TextBox tb = new TextBox();

            foreach (string pk in Settings.PK)
                if (lb.Text == pk)
                    tb.Enabled = false;
            try
            {
                lb = (LinkButton)gvData.HeaderRow.Cells[i].Controls[0];
                tb = (TextBox)
                    gvData.Rows[gvData.EditIndex].Cells[i].Controls[0];
            }
            catch { }

            if (lb.Text.Contains(Settings.AUTOEXP))
            {
                tb.TextMode = TextBoxMode.MultiLine;
                tb.Rows = 7;
            }

            tb.Text = Truncate.ToText(tb.Text);
            tb.CssClass = "input";
            tb.ID = lb.Text;
        }

    gvData.DataBind();
}

这里应用程序将某些文本框设置为多行,并且它们都具有“输入”类。 使用 gvData.DataBind();没有应用任何修改。如果我删除 DataBind,它会起作用。 但在这里我面临另一个问题。我正在使用这些值来更新数据库。

protected void gvData_RowUpdating(object sender, GridViewUpdateEventArgs e)
{        
    string updateCommand = "UPDATE " + Settings.TABLE + "SET ";
    TextBox tb = new TextBox();

    for (int i = 1; i < gvData.HeaderRow.Cells.Count; i++)
    {
        LinkButton lb = new LinkButton();

        lb = (LinkButton)gvData.HeaderRow.Cells[i].Controls[0];

        try 
        {
            tb = (TextBox)gvData.Rows[e.RowIndex].Cells[i].Controls[0];

            if (tb.Text.Length > 0 && !Settings.PK.Contains(lb.Text))
                try
                {
                    Convert.ToDouble(tb.Text);
                    updateCommand += lb.Text + " = " + tb.Text + ", ";
                }
                catch { updateCommand += lb.Text + " = " + "'" + tb.Text + "', "; } 
        }
        catch { }
    }

    updateCommand = updateCommand.Remove(updateCommand.Length - 2, 2) + " WHERE";

    foreach (string pk in Settings.PK)
    {
        updateCommand += " " + pk + " = :" + pk + " AND";
        DS.UpdateParameters.Add(
            new Parameter(pk, TypeCode.String, e.Keys[pk].ToString()));
    }

    DS.UpdateCommand = updateCommand.Remove(updateCommand.Length - 4, 4);

    gvData.DataBind();
}

这里应用程序将 UpdateCommand 设置为数据源。从文本框中接收值。如果我使用 gvData.DataBind();在 PreRender 中,我能够从文本框中获取值,但样式不起作用。如果我不使用 DataBind,样式化 wotks 但文本框值是空的。

你有什么建议吗?提前谢谢你!


protected void gvData_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        for (int i = 1; i < e.Row.Cells.Count; i++)
        {
            try
            {
                LinkButton lb = (LinkButton)gvData.HeaderRow.Cells[i].Controls[0];
                lb.ToolTip = select.ToolTip(lb.Text);

                if (lb.Text.Contains(Settings.AUTOEXP))
                {
                    e.Row.Cells[i].ToolTip =
                        Truncate.ToText(e.Row.Cells[i].Text);
                    e.Row.Cells[i].Text =
                        Truncate.ToText(e.Row.Cells[i].Text
                            .Substring(0, 40)) + "...";
                }

                e.Row.DataItem = lb.Text;
                e.Row.Cells[i].Wrap = false;
            }
            catch { }

        }

        if ((e.Row.RowState & DataControlRowState.Edit) > 0)
        {
            for (int i = 1; i < e.Row.Cells.Count; i++)
            {
                LinkButton lb = new LinkButton();
                TextBox tb = new TextBox();

                foreach (string pk in Settings.PK)
                    if (lb.Text == pk)
                        tb.Enabled = false;
                try
                {
                    lb = (LinkButton)gvData.HeaderRow.Cells[i].Controls[0];
                    tb = (TextBox)
                        e.Row.Cells[i].Controls[0];
                }
                catch { }

                if (lb.Text.Contains(Settings.AUTOEXP))
                {
                    tb.TextMode = TextBoxMode.MultiLine;
                    tb.Rows = 7;
                }

                tb.Text = Truncate.ToText(tb.Text);
                tb.CssClass = "input";
                tb.ID = lb.Text;
            }
        }
    }

    if (e.Row.RowType == DataControlRowType.Footer)
        PopulateFooter(e.Row);

}

【问题讨论】:

  • 请验证您的输入以防止 sql 注入攻击并使用 Double.TryParse() 而不是 try catch 块。
  • 感谢您的评论。不过,您对这个问题有什么建议吗?
  • 从数据库返回的列数是动态的吗?我想知道您为什么不为该特定列使用 ASP:TemplateColumn。
  • 它是动态的。今天有超过 30 列,随着时间的推移,这个数字可能会发生变化。

标签: c# asp.net gridview datasource


【解决方案1】:

我建议使用 onrowdatabound 事件处理程序来处理更改文本框的显示。

【讨论】:

  • 我试过了,结果和运行 gvData.DataBind(); 一样在预渲染中
  • 对不起,结果和我没有添加 gvData.DataBind(); 一样,我得到空值
  • 如果我把 gvData.DataBind();在 RowUpdating 开始时,我会得到旧值
  • 在页面加载中尝试单个数据绑定。 if page.isnotpostback gv.databind();
  • 同样的事情。它会应用样式和多行,但不会在文本框中给我任何价值
【解决方案2】:

想通了。

由于某种原因,问题出在一行:

tb.ID = lb.Text; 

RowDataBounnd 中的代码是不必要的。

解决办法是:

在Page_Load中添加

GridView.DataBind();

行数据绑定:

if ((e.Row.RowState & DataControlRowState.Edit) > 0)
   for (int i = 1; i < e.Row.Cells.Count; i++)
       try
       {
          LinkButton lb = (LinkButton)gvData.HeaderRow.Cells[i].Controls[0];
          TextBox tb = (TextBox)e.Row.Cells[i].Controls[0];

          if (lb.Text.Contains(Settings.AUTOEXP))
          {
              tb.TextMode = TextBoxMode.MultiLine;
              tb.Rows = 7;
          }

          tb.CssClass = "input";
       }
       catch { }

在 RowUpdating 中,值是从 TextBox 访问的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多