Это комментарий к моему комментарию к ответу stevendaniels (см. выше):
В первом разделе кода выше range.setStart (node, (range .startOffset - 1)); сбой при запуске первого слова в «узле», поскольку он пытается установить диапазон на отрицательное значение. Я попытался добавить логику, чтобы предотвратить это, но затем последующий range.setStart (node, range.startOffset + 1); возвращает все, кроме первой буквы первого слова. Кроме того, когда слова разделяются новой строкой, последнее слово в предыдущей строке возвращается в дополнение к щелкнутому слову. Итак, это требует некоторой работы.
blockquote>Вот мой код, чтобы сделать код расширения диапазона в этом ответе надежным:
while (range.startOffset !== 0) { // start of node range.setStart(node, range.startOffset - 1) // back up 1 char if (range.toString().search(/\s/) === 0) { // space character range.setStart(node, range.startOffset + 1);// move forward 1 char break; } } while (range.endOffset < node.length) { // end of node range.setEnd(node, range.endOffset + 1) // forward 1 char if (range.toString().search(/\s/) !== -1) { // space character range.setEnd(node, range.endOffset - 1);// back 1 char break; } }
В родительском повторителе прикрепите метод к событию OnItemDataBound и в методе найдите вложенный повторитель и привяжите его к данным.
Example (.aspx):
<asp:Repeater ID="ParentRepeater" runat="server" OnItemDataBound="ItemBound">
<ItemTemplate>
<!-- Repeated data -->
<asp:Repeater ID="ChildRepeater" runat="server">
<ItemTemplate>
<!-- Nested repeated data -->
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:Repeater>
Example (.cs):
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ParentRepeater.DataSource = ...;
ParentRepeater.DataBind();
}
}
protected void ItemBound(object sender, RepeaterItemEventArgs args)
{
if (args.Item.ItemType == ListItemType.Item || args.Item.ItemType == ListItemType.AlternatingItem)
{
Repeater childRepeater = (Repeater)args.Item.FindControl("ChildRepeater");
childRepeater.DataSource = ...;
childRepeater.DataBind();
}
}
Вот пример того, как это сделать: Статья для управления вложенным повторителем
Я бы добавил событие DataBinding в сам дочерний повторитель:
<asp:Repeater ID="parentRepeater" runat="server">
<asp:Repeater ID="childRepeater" runat="server"
OnDataBinding="childRepeater_DataBinding" />
</asp:Repeater>
Затем просто реализуйте его:
protected void childRepeater_DataBinding(object sender, System.EventArgs e)
{
Repeater rep = (Repeater)(sender);
int someIdFromParentDataSource = (int)(Eval("ParentID"));
// Assuming you have a function call `GetSomeData` that will return
// the data you want to bind to your child repeater.
rep.DataSource = GetSomeData(int);
rep.DataBind();
}
Я предпочитаю делать это на уровне элемента управления, а не на уровне ItemDataBound
, чтобы, если вам когда-нибудь придется удалить элементы управления или элементы в ваших шаблонах, вам не нужно было беспокоиться о поиске кода в родительских элементах управления, которые его используют. Все локализуется вместе с самим элементом управления. Кроме того, вам никогда не придется выполнять FindControl
.
Если в будущем вы захотите заменить элемент управления, вы можете просто удалить его, и ваш код будет работать, поскольку он является самодостаточным. Использование ItemDataBound
приведет к тому, что ваш код будет компилироваться, но аварийно завершаться или неожиданно работать во время выполнения из-за зависимости от дочерних элементов управления.
Если мне нужно это сделать, я обычно использую событие ItemDataBound родительского репитера для привязки дочернего репитера. Если e - ваш параметр EventArgs, у вас будет доступ к дочернему ретранслятору через e.Item.FindControl () и доступ к данным через e.Item.DataItem.
Вот как это делается:
DataSource='<%# ((System.Data.DataRowView)Container.DataItem)[3] %>'
Итак, если вы знаете столбец в родительской таблице, который содержит дочернюю таблицу / источник данных для вложенного повторителя, вы можете поместить его прямо в файл aspx.