ASP.NET:Как получить доступ к элементам ввода формы, сгенерированным ретранслятором?

StackOverflow https://stackoverflow.com/questions/179938

  •  05-07-2019
  •  | 
  •  

Вопрос

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

<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> контролировать?я понимаю, что идентификатор элемента управления на стороне сервера не совпадает с идентификатором, который будет присутствовать на клиенте.

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

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

Должен ли я FindControl?

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);
      }
   }
}

Элемент данных элементов повторителя все еще присутствует в обработчике событий click?

Это было полезно?

Решение

Используйте серверный элемент управления вместо ввода элемента управления 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 оператор, если наличие элемента управления не гарантировано.

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

ctl00_cph0_ParentContainer_MyRepeater_ctl01_MyCheckbox
ctl00_cph0_ParentContainer_MyRepeater_ctl02_MyCheckbox
ctl00_cph0_ParentContainer_MyRepeater_ctl03_MyCheckbox

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

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

Другие советы

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

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

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

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

РАЗМЕТКА:

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

C#:

{

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

{ /* do something with hiddenField.Value */

}

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

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;
        }
    }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top