如何以编程方式将GridView添加到UpdatePanel中

6
我无法弄清如何以编程方式向UpdatePanel添加带有按钮的GridView。
我可以使用简单的控件,例如按钮和标签,但是当我尝试添加带有按钮的GridView时,会发生完整的Postback()。
<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">


protected override void OnInit(EventArgs e)
{
UpdatePanel up1 = new UpdatePanel();
    up1.ID = "UpdatePanel1";



    Button button1 = new Button();
    button1.ID = "Button1";
    button1.Text = "Submit";
    button1.Click += new EventHandler(Button_Click);


    Label label1 = new Label();
    label1.ID = "Label1";
    label1.Text = "A full page postback occurred.";


    GridView gv1 = new GridView();
    //Where the xml gets bonded to the data grind
    XmlDataSource xds = new XmlDataSource();
    xds.Data = xml;
    xds.DataBind();
    xds.EnableCaching = false;

    gv1.DataSource = xds;
    createButton(gv1, up1);
    gv1.RowCommand += new GridViewCommandEventHandler(CustomersGridView_RowCommand);
    gv1.DataBind();




    up1.ChildrenAsTriggers = true;

    up1.ContentTemplateContainer.Controls.Add(button1);
    up1.ContentTemplateContainer.Controls.Add(label1);

    up1.ContentTemplateContainer.Controls.Add(gv1);

    Page.Form.Controls.Add(up1);
}

protected void Page_Load(object sender, EventArgs e)
{


}
public void CustomersGridView_RowCommand(Object sender, GridViewCommandEventArgs e)
{
    if (e.CommandName == "buttonClicked")
    {
        int index = Convert.ToInt32(e.CommandArgument);

    }
}

void createButton(GridView g)
{
    ButtonField tea = new ButtonField();
    tea.ButtonType = ButtonType.Image;
    tea.ImageUrl = "~/checkdailyinventory.bmp";
    tea.CommandName = "buttonClicked";
    tea.HeaderText = "space";
    g.Columns.Add(tea);
}

protected void Button_Click(object sender, EventArgs e)
{
    ((Label)Page.FindControl("Label1")).Text = "Panel refreshed at " +
        DateTime.Now.ToString();
}

</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>UpdatePanel Constructor Example</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Button ID="Button2" runat="server" Text="Button" />
        <asp:ScriptManager ID="ScriptManager1" runat="server" />
    </div>
    </form>
</body>
</html>

如果单击 GridView,不想引发完整的 PostBack(),又要在一个 UpdatePanel 中以编程方式添加带有按钮的 GridView ,该怎么做呢?

编辑:我尝试过的其他方法

   void gv1_RowDataBound(object sender, GridViewRowEventArgs e)
{
    AsyncPostBackTrigger t = new AsyncPostBackTrigger();
    t.ControlID = e.Row.Cells[0].ClientID;
    t.EventName = "blah";
    up1.Triggers.Add(t);
}

刚试了一下,不起作用。PlaceHolder1.Controls.Clear(); PlaceHolder1.Controls.Add(up1); //Page.Form.Controls.Add(up1); - user1301708
尝试将UpdateMode设置为UpdatePanelUpdateMode.Conditional。我正在阅读MSDN上关于同样问题的一些帖子。有个人遇到了JavaScript的问题,但这不是你的情况。另一个人可以通过这个UpdateMode设置使其工作。 - Andre Calil
我不知道确切的controlID,所以我写了一个函数(在原帖的编辑中)。但是这会给我带来以下错误:System.InvalidOperationException: 无法为UpdatePanel“UpdatePanel1”中的触发器找到ID为'ctl01_ctl00'的控件。 - user1301708
这有点奇怪,你应该能够检索到控件ID。如果Cells[0]包含按钮,请尝试将其装箱为Button,例如((Button)e.Row.Cells[0]).ID。 - Andre Calil
这很奇怪,它应该可以工作...无论如何,你考虑过采用KISS方法吗?(如果可能的话)在设计时简单地添加更新面板和嵌套面板,并向面板添加控件。 - Jupaol
显示剩余6条评论
2个回答

2

你不能在设计时将GridView放在里面,然后通过设置Visible=false来隐藏它吗?

如果你不知道需要重复多少个GridView,那么可以将GridView包装在ListView中。该概念在这里介绍:

这可能不是完美的解决方案,但我认为我应该提供它,因为我认为你已经遇到了瓶颈。


网格视图必须以编程方式添加,因为在运行时我不知道需要多少个。 - user1301708
添加了一个额外的想法,可以涵盖这种情况。 - rtpHarry

2

根据:

我不介意在设计时创建更新面板。我只需要能够以编程方式添加内容(例如包含按钮的网格视图表),然后能够执行部分后台处理。

基本上,我使用了您的代码并进行了小修改:

  • Init事件中删除绑定,并在Load事件中执行它

  • 在设计时创建一个嵌套面板的UpdatePanel,然后将动态控件添加到该面板中

此代码将实现此功能(在我的环境中有效):

ASPX

    <asp:ScriptManager runat="server" />
    <asp:UpdatePanel runat="server">
        <ContentTemplate>
            <asp:Panel runat="server" ID="myPanel">
            </asp:Panel>
            <br />
            <asp:Label runat="server" ID="lblMessage"></asp:Label>
        </ContentTemplate>
    </asp:UpdatePanel>

代码后台

    protected void Page_Init(object sender, EventArgs e)
    {
        Button button1 = new Button();
        button1.ID = "Button1";
        button1.Text = "Submit";
        button1.Click += new EventHandler(Button_Click);

        Label label1 = new Label();
        label1.ID = "Label1";
        label1.Text = "A full page postback occurred.";

        var s1 = Builder<Product>.CreateListOfSize(15).Build();
        GridView gv1 = new GridView();
        gv1.DataSource = s1;
        createButton(gv1);
        gv1.RowCommand += new GridViewCommandEventHandler(CustomersGridView_RowCommand);

        this.myPanel.Controls.Add(button1);
        this.myPanel.Controls.Add(label1);
        this.myPanel.Controls.Add(gv1);
    }

    void createButton(GridView g)
    {
        ButtonField tea = new ButtonField();
        tea.ButtonType = ButtonType.Image;
        tea.ImageUrl = "~/checkdailyinventory.bmp";
        tea.CommandName = "buttonClicked";
        tea.HeaderText = "space";
        g.Columns.Add(tea);
    }

    protected void Button_Click(object sender, EventArgs e)
    {
        ((Label)Page.FindControl("Label1")).Text = "Panel refreshed at " +
            DateTime.Now.ToString();
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        this.DataBind();
    }

    public void CustomersGridView_RowCommand(Object sender, GridViewCommandEventArgs e)
    {
        if (e.CommandName == "buttonClicked")
        {
            //int index = Convert.ToInt32(e.CommandArgument);

            this.lblMessage.Text = DateTime.Now.ToString();
        }
    }

输出

输入图像描述


如果我想使用<asp:Table ID="Table1" runat="server"> </asp:Table>而不是面板,会有什么区别吗?我想让网格视图并排放置。 - user1301708
我认为那应该可以很好地工作,如果你遇到了一些问题,你可以动态创建表并将它们添加到“Panel”中。 - Jupaol
只有几个问题需要澄清。 为什么您要在Page_Load中添加绑定? 为什么需要点击两次才能开始异步?(我在进行一些测试后才注意到这一点) 我必须在“Page_Init”中完成吗?或者那是我可以编程添加Gridviews的唯一地方? - user1301708
它应该只需要一个点击就能工作(至少在我发布的代码环境中是这样)。微软的建议是在Init事件(使用MasterPage时)或PreInit(不使用MasterPage时)中创建动态控件。原因是在这些事件之后创建的控件,将在页面生命周期的后期引发其事件 [来源](http://msdn.microsoft.com/en-us/library/ms178472.aspx)。实际上,您可以在`Init`事件中调用`DataBind`方法,但最好的地方是在`Load`事件中(在`Load`中,ViewState已经被绑定)。 - Jupaol
顺便提一下,您可以使用以下代码:if (!this.IsPostBack) this.DataBind();,因为网格视图状态将在每个回发时保留其内容。 - Jupaol
如果(!this.IsPostBack)this.DataBind();使页面保持完全更新。 - user1301708

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接