但是你为什么要尝试注入一个按钮?
为什么不首先在标记中包含按钮?我真的看不出布局数据列表的必要性或理由,然后决定使用代码?
只需将一个按钮拖放到数据列表中,就完成了。
这是我们的数据列表 - 我们放入了一个平面简按钮。
<asp:DataList ID="DataList1" runat="server" DataKeyField="ID" >
<ItemTemplate>
<div style="border-style:solid;color:black;width:300px;margin-left:25px">
<div id="mybox" runat="server" style="padding:5px;text-align:right">
<p>Hotel Name: <asp:TextBox ID="HotelName" runat="server" Text ='<%# Eval("HotelName") %>' /></p>
<p>First Name: <asp:TextBox ID="FirstName" runat="server" Text ='<%# Eval("FirstName") %>' /></p>
<p>Last Name: <asp:TextBox ID="LastName" runat="server" Text ='<%# Eval("LastName") %>' /></p>
<p>City: <asp:TextBox ID="City" runat="server" Text ='<%# Eval("City") %>' /></p>
<p>Province: <asp:TextBox ID="Province" runat="server" Text ='<%# Eval("Province") %>' /></p>
Active: <asp:CheckBox ID="Active" runat="server" Checked = '<%# Eval("Active") %>'/>
<br />
<asp:Button ID="cmdRow" runat="server" Text="Row click This item"
/>
</div>
</div>
<div style="height:15px"></div>
</ItemTemplate>
</asp:DataList>
我们要填充的代码如下所示:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
MyLoadData();
}
void MyLoadData()
{
using (SqlConnection con = new SqlConnection(Properties.Settings.Default.TEST4))
{
string strSQL = "SELECT TOP 3 * FROM tblHotels ORDER BY HotelName";
using (SqlCommand cmdSQL = new SqlCommand(strSQL, con))
{
con.Open();
DataList1.DataSource = cmdSQL.ExecuteReader();
DataList1.DataBind();
}
}
我们现在有了这个:
现在,让我们连接按钮单击,如下所示:
所以,在上面创建新事件(inteli-sense 提供此选项)。
protected void cmdRow_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
DataListItem gRow = (DataListItem)btn.Parent;
Debug.Print("Row index = " + gRow.ItemIndex.ToString());
int pkID = (int)(DataList1.DataKeys[gRow.ItemIndex]);
Debug.Print("Data base PK id = " + pkID.ToString());
Debug.Print("Hotel name = " + ((TextBox)(gRow.FindControl("HotelName"))).Text);
Debug.Print("City = " + ((TextBox)(gRow.FindControl("City"))).Text);
Debug.Print("--------------------");
}
输出是这样的:
Row index = 1
Data base PK id = 72
Hotel name = Banff Rocky Mountain Resort
City = Banff
--------------------
所以,根本不清楚为什么要花费时间、精力和编写代码,而通常情况下,您只需将设计器中的一个好的旧飞机简按钮直接放入数据列表中,并且然后简单地连接一个事件。
编辑:
你可以把马牵到水边——但你能让马喝水吗?
如前所述,您可以注入一个按钮,但我真的但真的但真的不建议这样做。
但是,要使按钮单击事件起作用,您可以这样做:
HtmlButton btn = new HtmlButton();
btn.InnerText = "Index " + e.Item.ItemIndex;
btn.Attributes.Add("onclick","__doPostBack('BtnTest2','')");
btn.ViewStateMode = ViewStateMode.Enabled;
HtmlGenericControl MyDiv = (HtmlGenericControl)e.Item.FindControl("mybox");
MyDiv.Controls.Add(btn);
编辑2:
好的,似乎存在持久性问题。
因此,添加必须在页面加载时进行(或者可以更早)。
并且每次回传时都必须重新插入按钮。
现在可以了:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
MyLoadData();
}
AddBtns();
}
void MyLoadData()
{
using (SqlConnection con = new SqlConnection(Properties.Settings.Default.TEST4))
{
string strSQL = "SELECT TOP 3 * FROM tblHotels ORDER BY HotelName";
using (SqlCommand cmdSQL = new SqlCommand(strSQL, con))
{
con.Open();
DataList1.DataSource = cmdSQL.ExecuteReader();
DataList1.DataBind();
}
}
}
void AddBtns()
{
foreach (DataListItem gRow in DataList1.Items)
{
Button btn = new Button();
btn.Text = "Index " + gRow.ItemIndex;
btn.ID = "Btn" + gRow.ItemIndex;
btn.Click += new EventHandler(BtnTest3);
HtmlGenericControl MyDiv = (HtmlGenericControl)gRow.FindControl("mybox");
MyDiv.Controls.Add(btn);
}
}
void BtnTest3(object sender, EventArgs e)
{
Debug.Print("buttn3 click");
}
注意两个变化:
我们不会仅在 !IsPostback 上添加/注入按钮。
我们每次在页面加载时都注入按钮
我们没有使用 Item 绑定事件。