2009-06-10 4 views
0

У меня есть, шаблонное управление с привязкой к данным, так и внутри шаблонной области создать элемент управления с обработчиком событий, например, так:ASP.NET: доступ DataItem из обработчика событий

<tnl:DisplayTree ID="DisplayTree1" runat="server" KeyPropertyName="Id" 
ParentPropertyName="ParentDemographic" DataSourceID="DemographicObjectSource"> 
<ItemTemplate> 
    <asp:CheckBox ID="DemogSelector" runat="server" OnCheckedChanged="DemogSelector_OnCheckedChanged" /> &nbsp; 
    <asp:Label ID="InlineEditLabel" runat="server" Text='<%#DataBinder.Eval(Container.DataItem, "Name") %>'></asp:Label> 
    </ItemTemplate> 
</tnl:DisplayTree> 

В рамках мероприятия обработчик, я хотел бы иметь возможность обнаруживать Ключ элемента, для которого был создан элемент управления. Например:

protected void DemogSelector_OnCheckedChanged(object sender, EventArgs e) 
{ 
    CheckBox selector = (CheckBox)sender; 
    DisplayTree.TreeNode treeNode = (DisplayTree.TreeNode)selector.Parent.Parent.Parent.Parent; 
    Label1.Text += (int)treeNode.Key + ", "; 
} 

Как вы можете видеть, этот подход требует тщательного знания иерархии внутри моего класса DisplayTree.TreeNode (то есть я должен знать, что sender.Parent.Parent.Parent.Parent где я буду найдите объект DisplayTree.TreeNode). Я хотел бы сделать это немного более надежным, так что если моя иерархия TreeNode изменится или что-то еще, я могу без проблем получить доступ к ключу. Каков наилучший способ сделать этот ключ доступным из обработчика событий?

ответ

2

Лучший способ для добавления пользовательских атрибут вашего флажка

<asp:CheckBox ID="DemogSelector" runat="server" oncheckedchanged="DemogSelector_CheckedChanged" AutoPostBack="true" key='<%# Eval("Id") %>'/> 

А затем к нему доступ с помощью

string key = (sender as CheckBox).Attributes["key"]; 
+0

Это больше похоже на то, что я искал. Я убеждаюсь, что это работает, и отмечаем его как правильный ответ. Ответ Джона похож на одно и то же, но похоже, что вы отправили сначала. :-) – StriplingWarrior

0

Один из возможных способов заключается в добавлении метода расширения к флажку, который находит TreeNode для вас, он может быть реализован как некоторый цикл, который рекурсивно ищет родителей до тех пор, пока не будет найден TreeNode.

Таким образом вы просто вызываете selector.FindTreeNode(), конечно, это не сработает при любом флажке, который вызывается вне вашей структуры.

+0

Я подумал об этом, но я ищу что-то более общее ... что-то, что я мог бы использовать как лучший пр. actice. Я также думал о применении метода расширения, такого как selector.FindParent (typeof (TreeNode)), но по-прежнему кажется, что должен быть лучший способ. – StriplingWarrior

0

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

public class TreeNodeCheckedChangedEventArgs : EventArgs 
{ 
    TreeNodeCheckedChangedEventArgs(int nodeKey) 
    { 
     NodeKey = nodeKey; 
    } 

    int NodeKey { get; private set; } 

} 
+0

Я использую настраиваемый элемент управления, поэтому при необходимости могу добавить его. Есть ли способ указать в моей разметке ASP.NET, что событие OnCheckedChanged на флажке должно пройти этот специализированный класс EventArgs, или мне также нужно создать собственную версию Checkbox? – StriplingWarrior

0

Вы можете установить значение атрибута в окошке

<asp:CheckBox ID="DemogSelector" runat="server" oncheckedchanged="DemogSelector_CheckedChanged" AutoPostBack="true" value='<%#DataBinder.Eval(Container.DataItem, "Id") %>' /> 

и получить на стороне сервера

string value = ((CheckBox)sender).Attributes["value"]; 
0

I'm, используя вид подобного решения, как другие, добавляя свой код, если это поможет:

В разметке:

<ItemTemplate> 
     <input type="checkbox" 
      value="<%# Container.DataItemIndex %>" name="CheckedItems" /> 
    </ItemTemplate> 

И в EventHandler:

string checkedItemRowIds = Request.Form["CheckedItems"]; 
+0

Это не совсем то, что я ищу, но это может быть полезно в других обстоятельствах.Как это справится с тем, что на странице будет несколько экземпляров CheckedItems? Проверено ли checkedItemRowIds с разделенным запятыми списком или чем-то еще? Вы понимаете, что все, что находится в ItemTemplate, будет повторяться много раз, верно? – StriplingWarrior

Смежные вопросы