有关asp:listview和多个动态创建的控件的问题

时间:2010-01-13 22:38:11

标签: c# asp.net listview user-controls

我有一个列表视图,显示在按钮单击时创建的文本框列表。我还希望在每个txtbox旁边创建一个标签,该标签会增加从步骤x到步骤x + 1的内容:

我是否需要为此创建另一个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;
}

EDIT ::

由于似乎有点混乱,我会试着澄清一下:

截至目前,我在列表视图中有一个文本框,下面有一个按钮。

 ________
| txtbox |
|________|
  _____
 |_btn_|

当您单击某个按钮时,它会生成另一个文本框,因此单击它会导致以下结果:

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

这些文本框用于创建流程中的步骤,因此我想要做的就是在每个生成的文本框旁边添加生成的标签,以说明它是哪一步。所以我希望它看起来像这样:

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

如果再次单击该按钮,则会生成另一个标签,其中包含文本“步骤4”

4 个答案:

答案 0 :(得分:1)

看起来你已经拥有了所需的所有代码......只缺少一件事......添加一个在Page_Load上设置为0的私有类变量。然后在ItemDataBound中增加它以获取当前步骤编号。然后为您的标签调用FindControl,就像文本框一样...并将lblStep.Text更改为“Step X”。不喜欢它。

答案 1 :(得分:1)

在将DataSource绑定到ListView之前,我建议将来在BindListView()中引用,创建一个新的对象列表,然后就可以轻松绑定,如下所示:

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

并简单地绑定Listview中的数据:

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

,加上你现在可以解除方法IncrementTextboxCount,还可以自定义Index值(make成“Step1”,现在是“1”)

答案 2 :(得分: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;
}

答案 3 :(得分: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(); 
    } 
}