Я пишу веб-страницу на C# .NET. В javascript есть функция GetElementsByTagName ... это хорошо для javascript, вызываемого со страницы .aspx. Мой вопрос: могу ли я получить такую функциональность из кода программной части C#?
-
Сценарий для любопытных: я использовал asp: Repeater для создания множества кнопок, а теперь я, по сути, пытаюсь создать кнопку, которая нажимала бы их все. Я попытался сохранить все кнопки в списке по мере их создания, но список очищается при каждой обратной передаче, поэтому я подумал, что могу попробовать описанный выше метод.





FindControl () или перебрать элементы управления на странице ...
For each ctl as Control in Me.Controls
If ctl.Name = whatYouWant Then
do stuff
Next 'ctl
- Если вы создаете элементы управления, вы должны установить их идентификаторы
Dim ctl as New Control()
ctl.ID = "blah1"
так далее...
FindControl (строка) не работает, потому что я не знаю их идентификаторы. VB имеет смысл, но я не знаю, что бы я использовал в C# в леях этого Me.Controls.
this.Controls - это эквивалент C#
Что ж, вы можете найти элементы управления с помощью метода FindControl страницы, но элементы Repeater имеют имена, созданные с помощью .net.
Кроме того, если вы действительно хотите, вы можете сохранить список кнопок в ViewState своей страницы (или, возможно, список их имен).
Я попытался сохранить List <Button> в ViewState, но получилось некрасиво - вещь разбилась, сказав, что не может сериализовать кнопки. List <String> может работать, но я попробую, если это не сработает. Спасибо.
Всякий раз, когда вы выполняете какую-либо обратную передачу, все воссоздается, включая элементы управления привязкой данных.
Если вашего списка больше нет, то исчезнут и кнопки управления. Если, конечно, вы не воссоздали их, и в этом случае вам также следовало воссоздать список.
К сожалению, последовательность выглядит так: -Создать кнопки / Список -Нажмите кнопку «Новая», которая нажимает все остальные кнопки: -Это вызывает обратную передачу, поэтому экран становится белым, и сразу после того, как он пытается развернуть кнопки ... которые не существовать. Я мог делать это неправильно, не знаю.
Похоже, ваша проблема связана с дизайном.
Попробуй это:
foreach (Control ctl in myRepeater.Controls)
{
if (ctl is Button)
{
((Button)ctl).Click();
}
}
HTH ...
вы пропустите кнопки, которые находятся в контейнерах, например, панели и прочее с этим методом. Я бы использовал рекурсивную функцию.
Но он сказал, что это в ретрансляторе. Рекурсия была бы излишней, не так ли?
Я не знаю точно, что вы имеете в виду, говоря "щелкают их все". Но как этот следующий код будет работать для вас? Не знаю, не тестировал ...
protected void Page_Load(object sender, EventArgs e)
{
foreach (Control control in GetControlsByType(this, typeof(TextBox)))
{
//Do something?
}
}
public static System.Collections.Generic.List<Control> GetControlsByType(Control ctrl, Type t)
{
System.Collections.Generic.List<Control> cntrls = new System.Collections.Generic.List<Control>();
foreach (Control child in ctrl.Controls)
{
if (t == child.GetType())
cntrls.Add(child);
cntrls.AddRange(GetControlsByType(child, t));
}
return cntrls;
}
еще лучше, вы можете добавить метод расширения в Control под названием GetControlsByType или что-то еще в этой строке ... Мне на самом деле больше нравятся методы расширения, они меня растут.
ASPX:
<%@ Page Language = "C#" AutoEventWireup = "true" CodeFile = "Default.aspx.cs" Inherits = "_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns = "http://www.w3.org/1999/xhtml">
<head runat = "server">
<title>Untitled Page</title>
</head>
<body>
<form id = "form1" runat = "server">
<asp:Repeater runat = "server" ID = "Repeater1">
<ItemTemplate>
<asp:Button runat = "server" ID = "Button1" Text = "I was NOT changed" />
</ItemTemplate>
</asp:Repeater>
</form>
</body>
</html>
ASPX.CS:
using System;
using System.Data;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(Object sender, EventArgs e)
{
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("column"));
DataRow dr = null;
for (Int32 i = 0; i < 10; i++)
{
dr = dt.NewRow();
dr["column"] = "";
dt.Rows.Add(dr);
}
this.Repeater1.DataSource = dt;
this.Repeater1.DataBind();
foreach (RepeaterItem ri in this.Repeater1.Controls)
{
foreach (Control c in ri.Controls)
{
Button b = new Button();
try
{
b = (Button)c;
}
catch (Exception exc)
{
}
b.Text = "I was found and changed";
}
}
}
}
Этот внутренний цикл был бы лучше много как: Button b = c as Button; if (b! = null) b.Text = "Меня нашли и изменили";
Или вариант моего собственного кода, изменяющий только ASPX.CS:
using System;
using System.Data;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Collections.Generic;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(Object sender, EventArgs e)
{
#region Fill Repeater1 with some dummy data
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("column"));
DataRow dr = null;
for (Int32 i = 0; i < 10; i++)
{
dr = dt.NewRow();
dr["column"] = "";
dt.Rows.Add(dr);
}
this.Repeater1.DataSource = dt;
this.Repeater1.DataBind();
#endregion
foreach (Button b in this.FindButtonsInRepeater(ref this.Repeater1))
{
b.Text = "I was found and changed";
}
}
private List<Button> FindButtonsInRepeater(ref Repeater repeater)
{
List<Button> buttonsFound = new List<Button>();
foreach (RepeaterItem ri in repeater.Controls)
{
foreach (Control c in ri.Controls)
{
try
{
buttonsFound.Add((Button)c);
}
catch (Exception exc)
{
}
}
}
return buttonsFound;
}
}
Если вы не измените объект, на который указывает ретранслятор, в параметре ref нет необходимости.
извините за vb. Я могу перевести если нужно