У меня есть небольшой пользовательский элемент управления, определенный как:
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="CompanyTree.ascx.cs" Inherits="RivWorks.Web.UserControls.CompanyTree" %>
<div class="PrettyTree">
<asp:TreeView runat="server"
ID="companyTree"
OnSelectedNodeChanged="SelectedNodeChanged"
OnAdaptedSelectedNodeChanged="SelectedNodeChanged" >
</asp:TreeView>
<asp:Label runat="server" ID="currentParentID" Text="" Visible="false" />
<asp:Label runat="server" ID="currentCompanyID" Text="" Visible="false" />
<asp:Label runat="server" ID="currentExpandDepth" Text="" Visible="false" />
<asp:Label runat="server" ID="currentValuePath" Text="" Visible="false" />
<asp:Label runat="server" ID="currentParentValuePath" Text="" Visible="false" />
<asp:Label runat="server" ID="currentCompanyUser" Text="" Visible="false" />
</div>
По какой-то причине события OnSelectedNodeChanged и OnAdaptedSelectedNodeChanged не запускаются, когда я нажимаю на узел в дереве. Я гуглил в течение последнего часа и не нашел ничего плохого.
Вот мои обработчики событий в коде позади.
#region Event Handlers
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
LoadCompanyTree();
TreeNode currentNode = companyTree.SelectedNode;
CompanyID = currentNode.Value;
ValuePath = currentNode.ValuePath;
if (currentNode.Parent != null)
{
ParentCompanyID = currentNode.Parent.Value;
ParentValuePath = currentNode.Parent.ValuePath;
}
else
{
ParentCompanyID = "";
ParentValuePath = "";
}
ExpandDepth = currentNode.Depth.ToString();
LoadCompany();
}
}
protected void SelectedNodeChanged(object sender, EventArgs e)
{
TreeNode currentNode = companyTree.SelectedNode;
CompanyID = currentNode.Value;
ValuePath = currentNode.ValuePath;
if (currentNode.Parent != null)
{
ParentCompanyID = currentNode.Parent.Value;
ParentValuePath = currentNode.Parent.ValuePath;
}
else
{
ParentCompanyID = "";
ParentValuePath = "";
}
ExpandDepth = currentNode.Depth.ToString();
LoadCompany();
}
#endregion
Я также включил код для построения дерева. Моя структура данных основана на http://articles.sitepoint.com/article/hierarchical-data-database.
private void LoadCompanyTree()
{
DataTable dtTree = RivWorks.Data.Companies.GetTree();
companyTree.Nodes.Clear();
companyTree.Nodes.Add(RivWorks.Web.Tree.BuildTree(dtTree, Page));
companyTree.ExpandDepth = 1;
companyTree.Nodes[0].Selected = true;
companyTree.Nodes[0].Select();
companyTree.ShowLines = true;
companyTree.RootNodeStyle.ImageUrl = Page.ResolveUrl(@"~/images/tree/root.png");
companyTree.ParentNodeStyle.ImageUrl = Page.ResolveUrl(@"~/images/tree/parent.png");
companyTree.LeafNodeStyle.ImageUrl = Page.ResolveUrl(@"~/images/tree/leaf.png");
companyTree.SelectedNodeStyle.Font.Bold = true;
companyTree.SelectedNodeStyle.Font.Italic = true;
if (CompanyID.Length > 0)
{
for (int i = 0; i < companyTree.Nodes.Count; i++)
{
if (companyTree.Nodes[i].Value.Equals(CompanyID, StringComparison.CurrentCultureIgnoreCase))
{
companyTree.ExpandDepth = companyTree.Nodes[i].Depth;
ValuePath = companyTree.Nodes[i].ValuePath;
companyTree.Nodes[i].Selected = true;
companyTree.Nodes[i].Select();
}
}
}
}
internal static TreeNode BuildTree(DataTable dtTree, System.Web.UI.Page myPage)
{
int left = 0;
int right = 0;
int index = 0;
Stack<int> rightStack = new Stack<int>();
Stack<TreeNode> treeStack = new Stack<TreeNode>();
TreeNode rootNode = new TreeNode(dtTree.Rows[index]["CompanyName"].ToString(), dtTree.Rows[index]["CompanyID"].ToString());
while (index < dtTree.Rows.Count)
{
left = Convert.ToInt32(dtTree.Rows[index]["left"]);
right = Convert.ToInt32(dtTree.Rows[index]["right"]);
if (rightStack.Count > 0)
{
while (rightStack.Peek() < right)
{
rightStack.Pop();
treeStack.Pop();
}
}
if (treeStack.Count == 0)
{
treeStack.Push(rootNode);
}
else
{
TreeNode treeNode = new TreeNode(dtTree.Rows[index]["CompanyName"].ToString(), dtTree.Rows[index]["CompanyID"].ToString());
treeStack.Peek().ChildNodes.Add(treeNode);
treeStack.Push(treeNode);
}
rightStack.Push(right);
index++;
}
return rootNode;
}
Когда я помещаю это в ASPX-страницу, она работает нормально. Когда я переместил его в пользовательский элемент управления ASCX, событие больше не запускается! Какие-либо советы / предложения по организации мероприятия?
ТИА
Примечание:
Я использую Адаптеры дружественного управления CSS, найденные на CodePlex. http://cssfriendly.codeplex.com/workitem/5519?PendingVoteId=5519 - отчет об ошибке события, которое не вызывается в пользовательском контроле (.ascx). Я добавил предложенный код плюс еще, и он все еще не срабатывает.
<MasterPage>
<Page>
<ContentHolder>
<User Control> <-- this should handle the event!
<TreeView with CSSFriendly Adapter>
код в адаптере:
public void RaiseAdaptedEvent(string eventName, EventArgs e)
{
string attr = "OnAdapted" + eventName;
if ((AdaptedControl != null) && (!String.IsNullOrEmpty(AdaptedControl.Attributes[attr])))
{
string delegateName = AdaptedControl.Attributes[attr];
Control methodOwner = AdaptedControl.Parent;
MethodInfo method = methodOwner.GetType().GetMethod(delegateName);
if (method == null)
{
methodOwner = AdaptedControl.Page;
method = methodOwner.GetType().GetMethod(delegateName);
}
// 2010.06.21 - keith.barrows - added to (hopefully) handle User Control (ASCX) coding...
// http://forums.asp.net/t/1249501.aspx
if (method == null)
{
Control parentUserControl = FindParentUserControl(AdaptedControl.Parent);
if (parentUserControl != null)
{
methodOwner = parentUserControl;
method = methodOwner.GetType().GetMethod(delegateName);
}
}
// 2010.06.21 - keith.barrows - added to (hopefully) handle User Control (ASCX) coding...
// http://cssfriendly.codeplex.com/workitem/5519?ProjectName=cssfriendly
if (method == null)
{
methodOwner = AdaptedControl.NamingContainer;
method = methodOwner.GetType().GetMethod(delegateName);
}
if (method == null)
{
methodOwner = AdaptedControl.Parent;
method = methodOwner.GetType().GetMethod(delegateName);
}
if (method != null)
{
object[] args = new object[2];
args[0] = AdaptedControl;
args[1] = e;
method.Invoke(methodOwner, args);
}
}
}
private Control FindParentUserControl(Control control)
{
if (control.Parent == null)
return null;
if (control.Parent is UserControl)
return control.Parent;
return FindParentUserControl(control.Parent);
}
Мне не хватает делегата или определения события? Адаптированный элемент управления ПРОСТО НЕ НАЙДЕТ метод для вызова!