2010-01-13 76 views
0

我有一個列表視圖,顯示按鈕單擊時創建的文本框列表。我還想在每個txtbox旁邊創建一個標籤,它將從步驟x開始遞增:步驟x + 1:有關asp:listview和多個動態創建的控件的問題

是否需要爲此創建另一個listview控件,或者是否更容易方式(我希望)?

這裏是我的列表視圖當前網頁代碼:

<tr align="center" valign="middle"> 
    <td> 
     <asp:ListView ID="lvDynamicTextboxes" runat="server" ItemPlaceholderID="itemPlaceholder" onitemdatabound="lvDynamicTextboxes_ItemDataBound"> 
      <LayoutTemplate> 
       <asp:PlaceHolder ID="itemPlaceholder" runat="server" /> 
      </LayoutTemplate> 
      <ItemTemplate> 
       <asp:Label ID="lblStep" runat="server" Text="Step 1:" /> 
       <asp:TextBox ID="txtStep" runat="server" TextMode="MultiLine" Rows="3" Width="300" style="margin-top:10px;" /> 
      </ItemTemplate> 
     </asp:ListView> 

     <br /><asp:Button ID="btnAddNewStep" runat="server" Text="Add another step" onclick="btnAddNewStep_Click" style="margin-top:5px;" /> 
    </td> 
</tr> 

這裏是代碼隱藏

protected void btnAddNewStep_Click(object sender, EventArgs e) 
{ 
    this.UpdateDataSource(); 
    this.IncrementTextboxCount(); 
    this.BindListView(); 
} 

private void BindListView() 
{ 
    //create an enumerable range based on the current count 
    List<string> dataSource = this.GetDataSource(); 

    //bind the listview 
    this.lvDynamicTextboxes.DataSource = dataSource; 
    this.lvDynamicTextboxes.DataBind(); 
} 

private void IncrementTextboxCount() 
{ 
    List<string> dataSource = this.GetDataSource(); 

    dataSource.Add(string.Empty); 
    this.SetDataSource(dataSource); 
} 

private List<string> GetDataSource() 
{ 
    List<string> dataSource = null; 

    if (ViewState[ "DataSource" ] != null) 
     dataSource = (List<string>)ViewState[ "DataSource" ]; 
    else 
    { 
     dataSource = new List<string>(); 
     dataSource.Add(string.Empty); 
     ViewState[ "DataSource" ] = dataSource; 
    } 

    return dataSource; 
} 

private void UpdateDataSource() 
{ 
    List<string> dataSource = new List<string>(); 

    foreach (ListViewItem item in this.lvDynamicTextboxes.Items) 
     if (item is ListViewDataItem) 
     { 
      TextBox txt = (TextBox)item.FindControl("txtStep"); 
      dataSource.Add(txt.Text); 
     } 

    this.SetDataSource(dataSource); 
} 

protected void lvDynamicTextboxes_ItemDataBound(object sender, ListViewItemEventArgs e) 
{ 
    if (e.Item is ListViewDataItem) 
    { 
     TextBox txt = (TextBox)e.Item.FindControl("txtStep"); 
     txt.Text = ((ListViewDataItem)e.Item).DataItem.ToString(); 
    } 
} 

private void SetDataSource(List<string> dataSource) 
{ 
    ViewState[ "DataSource" ] = dataSource; 
} 

編輯::

因爲似乎有一點混淆,我試圖澄清:

截至目前,我有一個文本框在列表視圖中的一個按鈕ü nderneath。

________ 
| txtbox | 
|________| 
    _____ 
|_btn_| 

當你點擊一個按鈕,它會產生另一個文本框,所以點擊兩次導致此:

________ 
| txtbox | 
|________| 
________ 
| txtbox | 
|________| 
________ 
| txtbox | 
|________| 
    _____ 
|_btn_| 

這些文本框是建立在一個工藝步驟,因此,所有我想do是在每個生成的文本框旁邊添加一個生成的標籤以說明它是哪一步。所以,我希望它看起來像這樣:

   ________ 
["Step 1"] | txtbox | 
       |________| 
       ________ 
["Step 2"] | txtbox | 
       |________| 
       ________ 
["Step 3"] | txtbox | 
       |________| 
       _____ 
       |_btn_| 

如果他們再次單擊該按鈕,然後用文本「第4步」

回答

0

我結束了爲包含標籤,然後把它們放在一個表中的另一個列表視圖的重複函數。這並不漂亮,但它的工作原理。我還在最新的文本框旁添加了刪除鏈接。只要有人看過代碼即可。

<table> 
    <tr> 
     <td valign="top"> 
      <asp:ListView ID="lvDynamicLabels" runat="server" ItemPlaceholderID="itemPlaceholder2" onitemdatabound="lvDynamicLabels_ItemDataBound"> 
       <LayoutTemplate> 
        <asp:PlaceHolder ID="itemPlaceholder2" runat="server" /> 
       </LayoutTemplate> 
       <ItemTemplate> 
        <asp:Label ID="lblStep" runat="server" Width="100px" style="margin-top:30px; margin-bottom:16px;" /> 
       </ItemTemplate> 
      </asp:ListView> 
     </td> 
     <td> 
      <asp:ListView ID="lvDynamicTextboxes" runat="server" ItemPlaceholderID="itemPlaceholder" onitemdatabound="lvDynamicTextboxes_ItemDataBound"> 
       <LayoutTemplate> 
        <asp:PlaceHolder ID="itemPlaceholder" runat="server" /> 
       </LayoutTemplate> 
       <ItemTemplate> 
        <asp:TextBox ID="txtStep" runat="server" TextMode="MultiLine" Rows="3" Width="275px" style="margin-top:10px;" /> 
       </ItemTemplate> 
      </asp:ListView> 

      <asp:LinkButton ID="lnkRemove" runat="server" Text="Remove" Visible="false" OnClick="lnkRemove_Click" style="font-size:small; position:absolute; margin-top:30px;" /> 

      <br /><asp:Button ID="btnAddNewStep" runat="server" Text="Add another step" onclick="btnAddNewStep_Click" style="margin-top:5px;" /> 
     </td> 
    </tr> 
</table> 

而後面的代碼:

protected void lnkRemove_Click(object sender, EventArgs e ) 
    { 
     UpdateDataSource(true); 
    UpdateLabelDataSource(true); 

    BindListView(); 
    BindLabelListView(); 

    if (lvDynamicTextboxes.Items.Count == 1) 
     lnkRemove.Visible = false; 
} 

private void BindListView() 
{ 
    List<string> dataSource = this.GetDataSource(); 

    this.lvDynamicTextboxes.DataSource = dataSource; 
    this.lvDynamicTextboxes.DataBind(); 
} 

private void IncrementTextboxCount() 
{ 
    List<string> dataSource = this.GetDataSource(); 

    dataSource.Add(string.Empty); 
    this.SetDataSource(dataSource); 
} 

private List<string> GetDataSource() 
{ 
    List<string> dataSource = null; 

    if (ViewState[ "DataSource" ] != null) 
     dataSource = (List<string>)ViewState[ "DataSource" ]; 
    else 
    { 
     dataSource = new List<string>(); 
     dataSource.Add(string.Empty); 
     ViewState[ "DataSource" ] = dataSource; 
    } 

    return dataSource; 
} 

private void UpdateDataSource(bool delete) 
{ 
    List<string> dataSource = new List<string>(); 

    foreach (ListViewItem item in this.lvDynamicTextboxes.Items) 
     if (item is ListViewDataItem) 
     { 
      TextBox txt = (TextBox)item.FindControl("txtStep"); 
      dataSource.Add(txt.Text); 
     } 

    if (delete) 
     dataSource.RemoveRange(dataSource.Count-1, 1); 

    this.SetDataSource(dataSource); 
} 

protected void lvDynamicTextboxes_ItemDataBound(object sender, ListViewItemEventArgs e) 
{ 
    if (e.Item is ListViewDataItem) 
    { 
     TextBox txt = (TextBox)e.Item.FindControl("txtStep"); 
     txt.Text = ((ListViewDataItem)e.Item).DataItem.ToString(); 
    } 
} 

private void SetDataSource(List<string> dataSource) 
{ 
    ViewState[ "DataSource" ] = dataSource; 
} 

private void BindLabelListView() 
{ 
    List<string> lblDataSource = this.GetLabelDataSource(); 

    //bind the listview 
    this.lvDynamicLabels.DataSource = lblDataSource; 
    this.lvDynamicLabels.DataBind(); 
} 

private void IncrementLabelCount() 
{ 
    List<string> lblDataSource = this.GetLabelDataSource(); 

    lblDataSource.Add("Step " + (lblDataSource.Count + 1)); 

    this.SetLabelDataSource(lblDataSource); 
} 

private List<string> GetLabelDataSource() 
{ 
    List<string> lblDataSource = null; 

    if (ViewState[ "lblDataSource" ] != null) 
     lblDataSource = (List<string>)ViewState[ "lblDataSource" ]; 
    else 
    { 
     lblDataSource = new List<string>(); 
     lblDataSource.Add("Step 1"); 
     ViewState[ "lblDataSource" ] = lblDataSource; 
    } 

    return lblDataSource; 
} 

private void UpdateLabelDataSource(bool delete) 
{ 
    List<string> lblDataSource = new List<string>(); 
    int count = 1; 

    foreach (ListViewItem item in this.lvDynamicLabels.Items) 
     if (item is ListViewDataItem) 
     { 
      Label lbl = (Label)item.FindControl("lblStep"); 
      lbl.Text = "Step " + count; 
      lblDataSource.Add(lbl.Text); 
      count++; 
     } 

    if (delete) 
     lblDataSource.RemoveRange(lblDataSource.Count-1, 1); 

    this.SetLabelDataSource(lblDataSource); 
} 

protected void lvDynamicLabels_ItemDataBound(object sender, ListViewItemEventArgs e) 
{ 
    if (e.Item is ListViewDataItem) 
    { 
     Label lbl = (Label)e.Item.FindControl("lblStep"); 
     lbl.Text = ((ListViewDataItem)e.Item).DataItem.ToString(); 
    } 
} 

private void SetLabelDataSource(List<string> lblDataSource) 
{ 
    ViewState[ "lblDataSource" ] = lblDataSource; 
} 
+0

中澄清這是奇怪的。究竟使用兩個ListView會讓你無法用一個ListView完成?您正在使用相同的數據源並同時綁定它們。你沒有看到這個問題? – Bryan 2010-01-16 00:14:51

+0

我確實說過它不漂亮。我知道這還不夠高雅,但我不明白如何控制列表視圖以使其更好。我已經用一個listview做了幾次嘗試,但是我一直在打牆。標籤根本不顯示,或者它們都具有相同的文本。 – Justen 2010-01-18 14:03:47

1

看起來你已經得到了所有的代碼,你產生的另一個標籤需要...只是缺少一件事...添加一個私人類變量,在Page_Load上設置爲0。然後在您的ItemDataBound中增加它以獲取當前步號。然後爲您的標籤調用FindControl,就像文本框一樣......並將lblStep.Text更改爲「Step X」。沒什麼好說的。

+0

順便說一句...這些並不是真正的「動態創建」控件。您應該爲您在代碼隱藏中定義和實例化的控件保留該術語,並將其添加到PlaceHolder或Controls集合中。即沒有在ASPX或ASCX中定義。大家都在同一頁面上。 :) – Bryan 2010-01-14 09:30:24

+0

哦,我假設這意味着它們沒有在aspx頁面中定義,而是在應用程序運行時創建。 – Justen 2010-01-14 17:01:28

+0

我想你可能會誤解。我想在每個文本框旁邊創建一個標籤,而不是隻有一個標籤並將其向下推。 – Justen 2010-01-14 19:28:29

0

我不明白你爲什麼結束了從分隔條件的文本框的標籤。爲什麼不離開模板,你有它最初,並在後面的代碼中有這樣的方法:

protected void lvDynamicLabels_ItemDataBound(object sender, ListViewItemEventArgs e) 
{ 
    if (e.Item is ListViewDataItem) 
    { 
     Label lbl = (Label)e.Item.FindControl("lblStep"); 
     lbl.Text = "Step " + (datasource.Count + 1).ToString(); 
     TextBox txt = (TextBox)e.Item.FindControl("txtStep"); 
     txt.Text = ((ListViewDataItem)e.Item).DataItem.ToString(); 
    } 
} 
+0

dataSource沒有被定義,如果我添加了我的方法來獲取數據源,那麼在每次點擊按鈕之後,標籤都會像他們應該那樣增加,但是每個標籤都具有相同的文本。 – Justen 2010-01-18 14:04:50

1

一個數據源綁定到ListView控件之前,我建議在BindListView()備查,創建自己的新列表對象,那麼你可以很容易地進行綁定,這樣的:

this.lvDynamicLabels.DataSource = 
    from items in lblDataSource 
    select new 
    { 
     Value = items, 
     Index = strings.IndexOf(items) + 1 
    }; 

,只需綁定數據列表視圖:

<asp:Label ... Text='<%# Bind(Index) %>' /> 
<asp:Button ... Text='<%# Bind("Value")%>' /> 

,再加上你現在可以拒絕方法IncrementTextboxCount,也自定義索引值(製作成「Step1」,現在它的「1」)