ASP.NET: Как получить доступ к сгенерированным повторителем элементам ввода формы? - PullRequest
10 голосов
/ 07 октября 2008

Я хочу, чтобы ретранслятор генерировал несколько флажков, например ::10000

<tr><td><input type="checkbox" name="t" value="11cbf4deb87" /> <input type="checkbox" name="a" value="33cbf4deb87" />stackoverflow.com</td></tr>
<tr><td><input type="checkbox" name="t" value="11cbf4deb88" /> <input type="checkbox" name="a" value="33cbf4deb87" />microsoft.com</td></tr>
<tr><td><input type="checkbox" name="t" value="11cd3f33a89" /> <input type="checkbox" name="a" value="33cbf4deb87" />gmail.com</td></tr>
<tr><td><input type="checkbox" name="t" value="1138fecd337" /> <input type="checkbox" name="a" value="33cbf4deb87" />youporn.com</td></tr>
<tr><td><input type="checkbox" name="t" value="11009efdacc" /> <input type="checkbox" name="a" value="33bf4deb87" />fantasti.cc</td></tr>

Вопрос 1: Как я могу отдельно ссылаться на каждый флажок, когда ретранслятор работает, чтобы я мог установить уникальное значение?

Должен ли я связать данные с чем-то вроде:

<itemtemplate>
   <tr>
      <td>
         <input type="checkbox" name="t" 
            value="<%# ((Item)Container.DataItem).TangoUniquifier %>" />
         <input type="checkbox" name="a" 
            value="<%# ((Item)Container.DataItem).AlphaUniquifier %>" />
         <%# ((Item)Container.DataItem).SiteName %>
      </td>
   </tr>
</itemtemplate>

Или я должен как-то установить его в OnItemDataBound?

<asp:repeater id="ItemsRepeater" 
      OnItemDataBound="ItemsRepeater_OnItemDataBound" runat="server">
   ...
   <itemtemplate>
      <tr>
         <td>
            <input id="chkTango" type="checkbox" name="t" runat="server" />
            <input id="chkAlpha" type="checkbox" name="a" runat="server" />
            <%# ((Item)Container.DataItem).SiteName %>
         </td>
      </tr>
   </itemtemplate>
   ...
</asp:repeater>


protected void ItemsRepeater_OnItemDataBound(object sender, RepeaterItemEventArgs e)
{
   // if the data bound item is an item or alternating item (not the header etc)
   if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
   {
      // get the associated item
      Item item = (Item)e.Item.DataItem;

      //???
      this.chkTango.Value = item.TangoUniquifier;
      this.chkAlpha.Value = item.AlphaUniquifier;
   }
}

Но если я должен ссылаться на него в коде позади, как мне ссылаться на него в коде сзади? Должен ли я ссылаться на него, используя свойство id (на стороне сервера) элемента управления <INPUT>? я понимаю, что идентификатор элемента управления на стороне сервера не совпадает с идентификатором, который будет присутствовать на клиенте.

Или я должен сделать что-то, где мне нужно найти элемент управления INPUT с именем "t", а другой - с именем "a"? И какой тип контроля это CheckBox, который позволяет мне устанавливать его входное значение?

protected void ItemsRepeater_OnItemDataBound(object sender, RepeaterItemEventArgs e)
{
   // if the data bound item is an item or alternating item (not the header etc)
   if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
   {
      // get the associated item
      Item item = (Item)e.Item.DataItem;

      CheckBox chkTango = (CheckBox)e.Item.FindControl("chkTango");
      chkTango.Value = item.TangoUniquifier;

      CheckBox chkAlpha = (CheckBox)e.Item.FindControl("chkAlpha");
      chkAlpha.Value = item.AlphaUniquifier;
   }
}

Вопрос 2: Когда позже пользователь нажимает кнопку ОТПРАВИТЬ, как мне найти все отмеченные флажки или, более конкретно, их ЗНАЧЕНИЯ?

Должен ли я найти элемент управления?

protected void DoStuffWithLinks_Click(object sender, EventArgs e)
{
   // loop through the repeater items
   foreach (RepeaterItem repeaterItem in actionItemRepeater.Items)
   {
      Item item = repeaterItem.DataItem as Item;

      // grab the checkboxes
      CheckBox chkAlpha = (CheckBox)repeaterItem.FindControl("chkAlpha");
      CheckBox chkTango = (CheckBox)repeaterItem.FindControl("chkTango");

      if (chkAlpha.Checked)
      {          
         item.DoAlphaStuff(chkAlpha.Name);
      }

      if (chkTango.Checked)
      {
         item.DoTangoStuff(chkTango.Name);
      }
   }
}

Элементы повторителя DataItem все еще присутствуют в обработчике события щелчка?

Ответы [ 4 ]

13 голосов
/ 08 октября 2008

Использование серверного элемента управления вместо создания элемента управления вводом runat = server

 <asp:CheckBox id="whatever" runat="Server" />

Когда вы устанавливаете значение в ItemDataBound, вы используете FindControl

CheckBox checkBox = (CheckBox)e.Item.FindControl("whatever");
checkBox.Checked = true;

Когда вы получаете элементы, вы также используете FindControl из элемента в конструкции foreach. Кроме того, в зависимости от того, как вы связываете данные, DataItem может перестать существовать после обратной передачи.

foreach (RepeaterItem item in myRepeater.Items)
{
    if (item.ItemType == ListItemType.Item 
        || item.ItemType == ListItemType.AlternatingItem) 
    { 
        CheckBox checkBox = (CheckBox)item.FindControl("whatever");
        if (checkBox.Checked)
        { /* do something */ }
    }
}
  • Многие люди склонны к «безопасному приведению», используя оператор as с FindControl(). Мне это не нравится, потому что когда вы изменяете имя элемента управления в форме, вы можете молча игнорировать ошибку разработки и усложнять ее отслеживание. Я пытаюсь использовать оператор as, только если контроль не гарантирован.

Обновление для: Какой CheckBox какой? В визуализированном html вы получите все эти имена флажков вроде

ctl00_cph0_ParentContainer_MyRepeater_ctl01_MyCheckbox
ctl00_cph0_ParentContainer_MyRepeater_ctl02_MyCheckbox
ctl00_cph0_ParentContainer_MyRepeater_ctl03_MyCheckbox

Тебе все равно, как называются имена, потому что foreach item.FindControl () получает их за тебя, и ты не должен ничего о них принимать. Однако, когда вы выполняете итерацию с помощью foreach, вам обычно нужен способ сослаться на это обратно. В большинстве случаев это достигается также наличием элемента управления asp: HiddenField рядом с каждым CheckBox для хранения идентификатора, чтобы сопоставить его с верной сущностью.

Примечание по безопасности : существует проблема безопасности с использованием скрытых полей, потому что скрытое поле может быть изменено в JavaScript; всегда помните, что это значение могло быть изменено пользователем до отправки формы.

4 голосов
/ 07 октября 2008

Возможно, вам будет проще использовать элемент управления CheckBoxList.

В простом случае вы должны установить для DataTextVield и DataValueField имя и значение, извлеченные из источника данных (при условии, что вы заполняете источник данных), а затем связать его для создания элементов.

Вероятно, меньше работы с вашей стороны, чем создание флажков в ретрансляторе.

2 голосов
/ 02 сентября 2009

Вот определенный код для обработки скрытого поля:

MARKUP:

<asp:HiddenField ID="repeaterhidden" Value='<%# DataBinder.Eval(Container.DataItem, "value")%>' runat="server" >

C #:

{

HiddenField hiddenField = (HiddenField)item.FindControl(repeaterStringhidden);

{ /* do something with hiddenField.Value */

}

1 голос
/ 16 марта 2012

Я считаю, что этот КБ дал мне лучший ответ:

http://msdn.microsoft.com/en-us/library/1d04y8ss.aspx

к моему собственному отсутствию удачи, это, кажется, доступно только для версии .net 4.0 (и я все еще застрял в 3.5 SP1).

цитата (жирный шрифт мой):

Когда элемент управления находится внутри элемента управления с привязкой к данным, который генерирует повторяющиеся экземпляры элемента управления, ASP.NET генерирует значения UniqueID и ClientID для каждого экземпляра элемента управления. Значение UniqueID генерируется путем объединения значения UniqueID контейнера именования, значения идентификатора элемента управления и порядкового номера. Это относится к элементам управления, таким как DataList, Repeater , GridView и ListView.

ASP.NET генерирует значения ClientID аналогичным образом, когда для свойства ClientIDMode установлено значение AutoID. Это может затруднить обращение к элементу управления в клиентском скрипте, поскольку обычно вы не можете предсказать значения используемых последовательных чисел. Если вы хотите получить доступ к элементам управления с привязкой к данным из клиентского скрипта, вы можете установить для свойства ClientIDMode значение Predictable. Это упрощает прогнозирование значений ClientID.

Если для ClientIDMode задано значение Predictable, вы можете также установить для свойства ClientIDRowSuffixDataKeys имя уникального поля данных , например первичного ключа в таблице базы данных. Это приводит к тому, что ASP.NET генерирует идентификатор клиента, который будет легче прогнозировать и ссылаться в клиентском скрипте, если вы сможете прогнозировать значения ключей данных.

Итак, в версии 3.5 я делаю это, используя скрытые поля:

    foreach (RepeaterItem item in rptClientes.Items)
    {
        Panel pnl = (Panel)item.FindControl("divCliente");
        Control c = pnl.FindControl("hdnID");
        if (c is HiddenField)
        {
            if (((HiddenField)c).Value == hdnClienteNome.Value)
                pnl.BackColor = System.Drawing.Color.Beige;
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...