Сделал как примеру из MSDN собственный иерархический источник данных. Но проблема в том, что когда я подвязываю этот источник к TreeView то у дерева у каждого TreeNode свойство DataItem == null. При том что DataPath правильный и DataBound == true.
Подскажите, как мне правильно вытащить DataItem для SelectedNode.
Код:
public class skmMenuXmlDataSource : HierarchicalDataSourceControl, IHierarchicalDataSource
{
private skmMenuXmlDataSourceView view = null;
protected override HierarchicalDataSourceView GetHierarchicalView(string viewPath)
{
if(null == view)
{
view = new skmMenuXmlDataSourceView(MenuXml, viewPath);
}
else
{
view.SetViewPath(viewPath);
}
return view;
}
// This class can be used declaratively. To enable
// declarative use, override the default implementation of
// CreateControlCollection to return a ControlCollection that
// you can add to.
protected override ControlCollection CreateControlCollection()
{
return new ControlCollection(this);
}
public String MenuXml
{
get
{
object o = ViewState["MenuXml"];
if(o != null)
return (string)o;
else
return String.Empty;
}
set
{
ViewState["MenuXml"] = value;
ViewState.SetItemDirty("MenuXml", true);
if(view != null)
{
view.SetMenuXml(value);
}
OnDataSourceChanged(EventArgs.Empty);
}
}
}
// The skmMenuXmlDataSourceView class encapsulates the
// capabilities of the skmMenuXmlDataSource data source control.
public class skmMenuXmlDataSourceView : HierarchicalDataSourceView
{
private string _viewPath;
private XmlDocument _document;
public void SetViewPath(string viewPath)
{
_viewPath = viewPath;
}
public void SetMenuXml(string menuXml)
{
_document = new XmlDocument();
_document.Load(HttpContext.Current.Server.MapPath(menuXml));
}
public skmMenuXmlDataSourceView(string menuXml, string viewPath)
: base()
{
// This implementation of HierarchicalDataSourceView does not
// use the viewPath parameter but other implementations
// could make use of it for retrieving values.
SetViewPath(viewPath);
SetMenuXml(menuXml);
}
// Starting with the rootNode, recursively build a list of
// FileSystemInfo nodes, create FileSystemHierarchyData
// objects, add them all to the FileSystemHierarchicalEnumerable,
// and return the list.
public override IHierarchicalEnumerable Select()
{
skmMenuXmlHierarchicalEnumerable fshe = new skmMenuXmlHierarchicalEnumerable();
String[] positions = _viewPath.Split('/');
if(positions.Length > 0)
{
string xpath = String.Format("/menu/menuItem");
for(int i = 1; i < positions.Length; i++)
{
xpath += String.Format("[{0}]/subMenu/menuItem", positions[i]);
}
foreach(XmlNode xmlNode in _document.SelectNodes(xpath))
{
fshe.Add(new skmMenuXmlHierarchyData(xmlNode));
}
}
return fshe;
}
}
// A collection of FileSystemHierarchyData objects
public class skmMenuXmlHierarchicalEnumerable : ArrayList, IHierarchicalEnumerable
{
public skmMenuXmlHierarchicalEnumerable()
: base()
{
}
public IHierarchyData GetHierarchyData(object enumeratedItem)
{
return enumeratedItem as IHierarchyData;
}
}
public class skmMenuXmlHierarchyData : IHierarchyData
{
private skmMenu.MenuItem _menuItemObject = null;
private XmlNode _xmlNode = null;
public skmMenuXmlHierarchyData(XmlNode node)
{
_xmlNode = node;
_menuItemObject = new skmMenu.MenuItem();
_menuItemObject.LoadFromXmlNode(_xmlNode);
}
// IHierarchyData implementation.
public bool HasChildren
{
get
{
return _xmlNode.SelectNodes("subMenu/menuItem").Count > 0;
}
}
public object Item
{
get
{
return this;
}
}
public string Type
{
get
{
return "skmMenuXmlHierarchyData";
}
}
public string Path
{
get
{
skmMenuXmlHierarchyData parent = (skmMenuXmlHierarchyData)GetParent();
int i=1;
XmlNode node = _xmlNode;
while((node = node.PreviousSibling) != null)
if(node.Name == "menuItem")
i++;
string path = (parent != null ? parent.Path : "")
+ "/" + i.ToString();
return path;
}
}
public IHierarchicalEnumerable GetChildren()
{
skmMenuXmlHierarchicalEnumerable children =
new skmMenuXmlHierarchicalEnumerable();
foreach(XmlNode node in _xmlNode.SelectNodes("subMenu/menuItem"))
{
children.Add(new skmMenuXmlHierarchyData(node));
}
return children;
}
public IHierarchyData GetParent()
{
XmlNode parent = _xmlNode.ParentNode;
if(parent != null)
{
switch(parent.Name)
{
case "subMenu":
parent = parent.ParentNode;
break;
case "menu":
parent = null;
break;
}
}
return parent != null ? new skmMenuXmlHierarchyData(parent) : null;
}
public override string ToString()
{
if(_menuItemObject != null)
{
return _menuItemObject.Text;
}
else
{
return String.Empty;
}
}
}
<xx:skmMenuXmlDataSource ID="x1" runat="server" MenuXml="menu.xml">
</xx:skmMenuXmlDataSource>
<asp:TreeView ID="TreeView1" runat="server" DataSourceID="x1" OnSelectedNodeChanged="TreeView1_SelectedNodeChanged" OnDataBound="TreeView1_DataBound" OnDataBinding="TreeView1_DataBinding">
</asp:TreeView>