我见过几个类似的问题,但没有一个解决方案适合我。我有一张桌子,我可以像下面这样添加几个按钮,我希望所有按钮都有一个共同的监听器:
Button b; //This is defined as a variable in class, not in a function
...
...
void someFunction( . . . )
{
foreach (DataRow row in table.Rows)
{
try
{
string starthour = row["starthour"].ToString(), endhour = row["endhour"].ToString(), day = row["day"].ToString(), building = row["building"].ToString(), room = row["room"].ToString();
int start = Convert.ToInt32(starthour.Substring(0, starthour.Length - 2));
int end = Convert.ToInt32(endhour.Substring(0, endhour.Length - 2));
int startindex = getHourIndex(start);
int endindex = getHourIndex(end);
int dayindex = getDayIndex(day);
for (int i = startindex; i < endindex; i++)
{
b = new Button();
b.Text = subj + numb + " " + section;
Color clr = getCourseColor(subj + numb + section, courses);
b.BackColor = clr;
b.Enabled = true;
b.Click += new EventHandler(button_Click);
table_filter_instructor_schedule.Rows[i].Cells[dayindex].Controls.Add(b);
}
}
catch (Exception)
{
}
}
}
这是事件处理程序:
protected void button_Click(object sender, EventArgs e)
{
Response.Redirect("Default.aspx");
}
但问题是,永远不会调用ebent handler函数。任何人都可以帮助我*
由于
编辑:以下是页面的外观,我想为这些按钮添加侦听器:
答案 0 :(得分:1)
如果您希望动态控件工作并引发事件,则需要在页面生命周期的早期重新创建它们(最近的Page_Init,Page_Load)。重新创建控件并为事件处理程序连接时,重要的是分配相同的ID。
使用动态创建的控件通常会增加很多复杂性,您应该检查是否没有其他更简单的方法。在您的函数中,您的按钮是基于数据表创建的。因此,使用转发器而不是动态创建的按钮可能是一种很好的方法。这允许静态地连接事件。
有关如何动态创建控件的详细示例,请参阅此link。但是,如果可能的话,它还建议采用静态方法:
现有控件通常可以提供您获得的功能 动态创建控件。例如,控件如 Repeater,DataList和RadioButtonList控件可以动态地进行 页面运行时创建行或其他控件元素。
在您的具体情况下(根据您的图片),我建议采用以下静态方法:
以下示例显示了主要部分(我仅添加了三天的列):
此Repeater创建一个非常基本的HTML表。请注意表行中的按钮和事件处理程序的静态注册。
<asp:Repeater ID="rptTimeTable" runat="server" OnItemDataBound="rptTimeTable_ItemDataBound">
<HeaderTemplate>
<table>
<thead>
<tr>
<td>Time</td>
<td>Mon</td>
<td>Tue</td>
<td>Wed</td>
</tr>
</thead>
<tbody>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><%# Eval("Time", "{0:t}") %></td>
<td>
<asp:Button ID="btnMon" runat="server" OnClick="btn_ClickHandler" />
</td>
<td>
<asp:Button ID="btnTue" runat="server" OnClick="btn_ClickHandler" />
</td>
<td>
<asp:Button ID="btnWed" runat="server" OnClick="btn_ClickHandler" />
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</tbody>
</table>
</FooterTemplate>
</asp:Repeater>
数据类存储我稍后在按钮上放置的每个按钮的文本。
public class RepeaterData
{
public DateTime Time { get; set; }
public string MonText { get; set; }
public string TueText { get; set; }
public string WedText { get; set; }
}
我把它放在Page_Load中(仅当它不是PostBack时),但你可以随时运行它。
var data = new List<RepeaterData>();
data.Add(new RepeaterData() { Time = DateTime.Today.AddHours(9), MonText = "123", TueText = null, WedText = null });
data.Add(new RepeaterData() { Time = DateTime.Today.AddHours(10), MonText = null, TueText = "456", WedText = "789" });
data.Add(new RepeaterData() { Time = DateTime.Today.AddHours(11), MonText = null, TueText = null, WedText = null });
data.Add(new RepeaterData() { Time = DateTime.Today.AddHours(12), MonText = "123", TueText = null, WedText = null });
rptTimeTable.DataSource = data;
rptTimeTable.DataBind();
protected void rptTimeTable_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
var data = (RepeaterData)e.Item.DataItem;
SetButtonText(e.Item, "btnMon", data.MonText);
SetButtonText(e.Item, "btnTue", data.TueText);
SetButtonText(e.Item, "btnWed", data.WedText);
}
}
private void SetButtonText(RepeaterItem repeaterItem, string btnId, string btnText)
{
var btn = repeaterItem.FindControl(btnId) as Button;
if (btn != null)
{
if (!string.IsNullOrEmpty(btnText))
btn.Text = btnText;
else
btn.Visible = false;
}
}
protected void btn_ClickHandler(object sender, EventArgs e)
{
// Do whatever you like
}
答案 1 :(得分:0)
问题是你在asp页面上生成动态按钮,生成的id必须在页面的生命周期内相同。如果不是,则在回发的服务器端无法找到该按钮。原因可能是您在请求处理中多次构建表。