Asp.net 动态添加的控件 无法局部刷新

妥妥 2012-02-11 10:32:12
我在页面用了UpdatePanel, 然后在后台动态添加了一个按钮和该按钮的点击事件,当我点击的时候页面不是局部刷新,郁闷。。。
...全文
289 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
妥妥 2012-02-11
  • 打赏
  • 举报
回复
我知道问题所在了 但是还没有解决方法 如果我是动态添加的Button则没事,如果我动态添加的是LinkButton,则页面会刷新。不解。。。
  • 打赏
  • 举报
回复
可以把它搞得复杂一点,注册更多的事件:

xxx.ascx
<%@ Control Language="C#" ClassName="XXX" %>
<%@ Import Namespace="System.Drawing" %>
<%@ Implements Interface="IXXX" %>
<script runat="server">
public override void DataBind()
{
base.DataBind();
DropDownList1.DataBind();
}

public string Name
{
get
{
var nm = ViewState["name"];
return (string)nm ?? "无名氏";
}
set
{
if (Name != value)
{
ViewState["name"] = value;
EnsureChildControls();
pName.DataBind();
}
}
}

public event Action NameChanged;

public string MarkedValue
{
get
{
EnsureChildControls();
return this.DropDownList1.SelectedValue;
}
}

protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
switch (this.DropDownList1.SelectedValue)
{
case "标记:红":
this.div.ForeColor = Color.Red;
break;
case "标记:蓝":
this.div.ForeColor = Color.Blue;
break;
case "标记:黑":
this.div.ForeColor = Color.Black;
break;
}
}

protected void LinkButton1_Click(object sender, EventArgs e)
{
Name = pName.Text;
if (NameChanged != null)
NameChanged();
}

private List<string> GetDropdownList1Datas()
{
return new List<string> { "标记:黑", "标记:红", "标记:蓝" };
}
</script>
<asp:TextBox runat="server" ID="pName" Text="<%# Name %>"></asp:TextBox>
先生(女士):      <asp:LinkButton ID="LinkButton1" runat="server"
OnClick="LinkButton1_Click">修改名字</asp:LinkButton>
<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged"
DataSource="<%# GetDropdownList1Datas() %>" />
<br />
<asp:Panel runat="server" ID="div">
你的合同付款期限已到,未付款<asp:TextBox runat="server" ID="pMoney" Width="60px" />元人民币,请及时付款。
<br />
<br />
XXX年XXX月XXX日
</asp:Panel>


aspx
<%@ Page Language="C#" %>

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

List<string> 插入的人物唯一编号
{
get
{
var x = ViewState["num"];
if (x == null)
{
x = new List<string>();
ViewState["num"] = x;
}
return (List<string>)x;
}
}

protected void Page_Load(object sender, EventArgs e)
{
this.PlaceHolder1.Controls.Clear();
for (var i = 0; i < 插入的人物唯一编号.Count; i++)
InsertAscx(插入的人物唯一编号[i], false); //注意第二个参数使用false
}

protected void Button1_Click(object sender, EventArgs e)
{
var 编号 = "sp" + (流水号++).ToString();
插入的人物唯一编号.Add(编号);
InsertAscx(编号, true); //注意第二个参数使用true
}

void InsertAscx(string 唯一编号, bool 是第一次生成控件)
{
var sub = new PlaceHolder { ID = "sub_" + 唯一编号 };
this.PlaceHolder1.Controls.Add(sub);
var c = this.LoadControl("XXX.ascx");
c.ID = "crt_" + 唯一编号;
sub.Controls.Add(c);
var b = new Button { Text = "删除", ID = "del_" + 唯一编号 };
sub.Controls.Add(b);
sub.Controls.Add(new LiteralControl { Text = " " });
var n = new Button { ID = "cnt_" + 唯一编号 };
sub.Controls.Add(n);
sub.Controls.Add(new LiteralControl { Text = "<hr />", ID = "hr_" + 唯一编号 });
if (是第一次生成控件)
{
b.Attributes["编号"] = 唯一编号;
((IXXX)c).Name = 唯一编号;
n.Text = "点击这里显示当前时间";
c.DataBind();
}
else
{
b.Click += (sender, e) =>
{
this.PlaceHolder1.Controls.Remove(this.PlaceHolder1.FindControl("sub_" + 唯一编号));
插入的人物唯一编号.Remove(唯一编号);
};
n.Click += (sender, e) =>
{
((Button)sender).Text = DateTime.Now.ToLongTimeString();
};
((IXXX)c).NameChanged += () =>
{
ScriptManager.RegisterStartupScript(this, typeof(Page), string.Empty,
string.Format("alert('{0}');", ((IXXX)c).Name.Replace("'", "\\'")), true);
};
}
}

private int 流水号
{
get
{
object x = ViewState["流水号"];
return x == null ? 1 : (int)x;
}
set
{
ViewState["流水号"] = value;
}
}

</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>演示动态增加\删除\编辑组件内容</title>
</head>
<body>
<form id="form1" runat="server">
<asp:Button ID="Button1" runat="server" Text="插入" OnClick="Button1_Click" /> 
<asp:Button ID="Button2" runat="server" Text="回发测试页面状态" UseSubmitBehavior="false" />
<hr />
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
</form>
</body>
</html>
  • 打赏
  • 举报
回复
而如果是你是交互操作时发现所谓“动态添加的控件”丢失了的问题,这其实是一个比较专业一点的asp.net动态控件的知识问题。我以前写过一个demo:http://topic.csdn.net/u/20090923/12/ce7c0782-69b3-421c-93e1-a51a00097d57.html

几乎所有的asp.net控件,为了给你一个类似winform一样的贴心的开发模式,几乎都会自动保持状态。如果这些直接写在设计页面上,那么当页面回发时,就会自动重建控件,然后asp.net会自动找到所有子控件而自动填入上一次输出html时的原始状态,然后在page_load处理之后才开始触发各个控件上的业务处理事件。

但是你自己用代码动态加载的控件,asp.net如果不调用你的创建代码,就无法恢复原来的控件架构(无法在同一个容器下面找到相同ID的子控件),也就无法给它填入上一次输出html时的状态。于是对这些也就不能支持类似winform那样的体验。

所以你可以看到我的demo在page_load中是有重建原来的(用户)控件的代码的。

只需要创建控件,并且设置跟原来完全一样的ID,其它的任何属性都不用设置,因为asp.net会随后自动重新从ViewState中根据这个ID而恢复出属性来。

但是asp.net在ViewState中并不保存事件处理程序的定义,所以你需要在Page_load中重建。否则就算控件从ViewState中恢复了正确的属性,也无法触发你自己注册的事件处理程序。
  • 打赏
  • 举报
回复
每当使用UpdatePanel,我都会立刻去把UpdateMode属性设置为Conditional。
jayrao5566 2012-02-11
  • 打赏
  • 举报
回复
设置 form 的 action
妥妥 2012-02-11
  • 打赏
  • 举报
回复
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<div id="divpp" runat="server">
//这里放的是动态添加的按钮
</div>
</ContentTemplate>
</asp:UpdatePanel>
妥妥 2012-02-11
  • 打赏
  • 举报
回复
就是放在里面的。。
qq623932737 2012-02-11
  • 打赏
  • 举报
回复
把按钮放到这UpdatePanel 里面啊

62,050

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧