Вопрос относительно asp: listview и нескольких динамически создаваемых элементов управления - PullRequest
0 голосов
/ 14 января 2010

У меня есть просмотр списка, который отображает список текстовых полей, которые создаются при нажатии кнопки. Я также хотел бы создать ярлык рядом с каждым txtbox, который будет увеличивать то, что говорится, с шага x: до шага x + 1:

Нужно ли для этого создать еще один элемент управления списком или есть более простой способ (который, я надеюсь)?

Вот текущий веб-код моего списка просмотра:

<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 ]

1 голос
/ 17 февраля 2011

Я бы предложил для будущей ссылки в BindListView (), прежде чем связывать DataSource с ListView, создайте себе новый список объектов, который затем вы можете легко связать, например:

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, а также настроить значение индекса (сделайте «Шаг1», теперь его «1»)

1 голос
/ 14 января 2010

Похоже, у вас есть весь код, который вам нужен ... просто пропущено что-то одно ... добавьте переменную частного класса, для которой в Page_Load установлено значение 0. Затем увеличьте его в ItemDataBound, чтобы получить номер текущего шага. Затем вызовите FindControl для вашей метки, как и для текстового поля ... и измените lblStep.Text на "Шаг X". Ничего себе.

0 голосов
/ 16 января 2010

Я не понимаю, почему вы отделили ярлык от текстового поля. Почему бы не оставить шаблон таким, каким он был изначально, и оставить этот метод в своем коде:

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 голосов
/ 16 января 2010

В итоге я создал дублирующие функции для другого списка, который содержал метки, и затем поместил их в таблицу. Это не красиво, но это работает. Я также добавил ссылку для удаления рядом с новейшим текстовым полем. Просто хедз-ап для тех, кто просматривает код.

<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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...