📄 treeview.cs
字号:
}
else if (obj is TreeNodeType)
{
_TreeNodeTypes.Add((TreeNodeType)obj);
}
}
/// <summary>
/// Overridden. Verifies certain properties.
/// </summary>
/// <param name="e">An EventArgs object that contains the event data.</param>
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
Controls.Clear();
// Databind from XML source
if (!Page.IsPostBack)
{
ReadTreeNodeTypeXmlSrc();
ReadTreeNodeXmlSrc();
foreach (TreeNode node in Nodes)
{
node.OnInit();
}
}
}
/// <summary>
/// On a postback, review state information so we can expand nodes as needed
/// </summary>
/// <param name="e"> </param>
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
_bCreated = true; // first chance to do this on non-postback
// initialize SelectedNodeIndex, if needed
if ((SelectedNodeIndex == "" || SelectedNodeIndex == String.Empty) && Nodes.Count > 0)
SelectedNodeIndex = "0";
TreeNode node = GetNodeFromIndex(SelectedNodeIndex);
if (node != null)
node.Selected = true;
}
/// <summary>
/// Overridden. Creates an EmptyControlCollection to prevent controls from
/// being added to the ControlCollection.
/// </summary>
/// <returns>An EmptyControlCollection object.</returns>
protected override ControlCollection CreateControlCollection()
{
return new EmptyControlCollection(this);
}
/// <summary>
/// Determines whether the FORMAT of the given index string is valid
/// (this is, containing only digits and periods). No validation of the
/// actual index being referenced is made.
/// </summary>
/// <param name="strIndex">Index to validate</param>
/// <returns>true if valid, false otherwise</returns>
private bool IsValidIndex(string strIndex)
{
if (strIndex == null || strIndex == String.Empty)
return true;
Regex r = new Regex("[^0-9.]");
if (r.IsMatch(strIndex)) // a character other than a digit or .
return false;
if (strIndex[0] == '.') // mustn't begin with a .
return false;
if (strIndex.IndexOf("..") != -1) // mustn't have two consecutive periods
return false;
return true;
}
/// <summary>
/// Returns the TreeNode at the given index location
/// </summary>
/// <param name="strIndex">string of dot-separated indices (e.g. "1.0.3") where
/// each index is the 0-based position of a node at the next deeper level of the tree</param>
/// <returns>The TreeNode, if found, or null</returns>
public TreeNode GetNodeFromIndex(string strIndex)
{
if (strIndex != null && strIndex.Length != 0)
{
// convert index string into array of strings
string[] a = strIndex.Split(new Char[] {'.'});
int i = 0;
int index;
TreeNodeCollection colNodes = Nodes;
while (i < a.GetLength(0) - 1)
{
index = Convert.ToInt32(a[i]);
if (index >= colNodes.Count)
return null;
colNodes = colNodes[index].Nodes;
i++;
}
index = Convert.ToInt32(a[i]);
if (index >= colNodes.Count)
return null;
else
return colNodes[index];
}
else
{
return null;
}
}
/// <summary>
/// Process data being posted back.
/// </summary>
/// <param name="strData">The data that was posted.</param>
/// <returns>true if data changed, false otherwise.</returns>
protected override bool ProcessData(String strData)
{
if (strData == null || strData == String.Empty)
return false;
// Split data using the pipe character as a delimeter
String[] astrData = strData.Split(new Char[] {'|'});
// Extract whether the tree was focused before the postback
if (astrData[0] == "1")
_bFocused = true;
// Extract the hovered node index
HoverNodeIndex = astrData[1];
// Extract the scroll top value
if (astrData[2] != String.Empty)
{
try
{
_scrollTop = Convert.ToInt32(astrData[2]);
}
catch
{
// Ignore
}
}
// Extract the scroll left value
if (astrData[3] != String.Empty)
{
try
{
_scrollLeft = Convert.ToInt32(astrData[3]);
}
catch
{
// Ignore
}
}
// Extract the parent's scroll top value
if (astrData[4] != String.Empty)
{
try
{
_parentTop = Convert.ToInt32(astrData[4]);
}
catch
{
// Ignore
}
}
// Extract the parent's scroll left value
if (astrData[5] != String.Empty)
{
try
{
_parentLeft = Convert.ToInt32(astrData[5]);
}
catch
{
// Ignore
}
}
// Extract the queued events
if (astrData[6] != null && astrData[6] != String.Empty)
return ProcessEvents(astrData[6]);
return false;
}
/// <summary>
/// Called when a downlevel browser submits the form
/// </summary>
/// <param name="eventArg">Event argument.</param>
protected override void RaisePostBackEvent(string eventArg)
{
ProcessEvents(eventArg);
RaisePostDataChangedEvent();
}
/// <summary>
/// Called when the TreeView on the client-side submitted the form.
/// </summary>
/// <param name="eventArg">Event argument.</param>
protected bool ProcessEvents(string eventArg)
{
if (eventArg == null || eventArg == String.Empty || eventArg == " ") // Don't know why, but the framework is giving a " " eventArg instead of null
return false;
TreeNode tn = null;
String[] events = eventArg.Split(new Char[] {';'});
foreach (string strWholeEvent in events)
{
String[] parms = strWholeEvent.Split(new Char[] {','});
if (parms[0].Length > 0)
{
if (parms[0].Equals("onselectedindexchange") && parms.GetLength(0) == 3)
{
TreeViewSelectEventArgs e = new TreeViewSelectEventArgs(parms[1], parms[2]);
tn = GetNodeFromIndex(parms[2]);
if (tn != null)
tn.LowerPostBackEvent(parms[0]);
DoSelectedIndexChange(e);
_eventList.Add("s");
_eventList.Add(e);
}
else if ((parms[0].Equals("onexpand") || parms[0].Equals("oncollapse") || parms[0].Equals("oncheck")) && parms.GetLength(0) == 2)
{
TreeViewClickEventArgs e = new TreeViewClickEventArgs(parms[1]);
if (parms[0].Equals("onexpand"))
_eventList.Add("e");
else if (parms[0].Equals("oncollapse"))
_eventList.Add("c");
else
_eventList.Add("k");
_eventList.Add(e);
tn = GetNodeFromIndex(parms[1]);
if (tn != null)
tn.LowerPostBackEvent(parms[0]);
}
}
}
if (_eventList.Count > 0)
return true;
else
return false;
}
/// <summary>
/// Fires pending events from a postback
/// </summary>
protected override void RaisePostDataChangedEvent()
{
for (int i = 0; i < _eventList.Count; i += 2)
{
String str = (String)_eventList[i];
if (str == "s")
OnSelectedIndexChange((TreeViewSelectEventArgs)_eventList[i + 1]);
else if (str == "e")
OnExpand((TreeViewClickEventArgs)_eventList[i + 1]);
else if (str == "c")
OnCollapse((TreeViewClickEventArgs)_eventList[i + 1]);
else
OnCheck((TreeViewClickEventArgs)_eventList[i + 1]);
}
_eventList.Clear();
}
/// <summary>
/// Reads the XML file specified in XmlSrc and creates TreeNodes accordingly. The
/// file is assumed to be valid XML with a TREENODES outer container and TREENODE
/// inner containers.
/// </summary>
/// <param name="TreeNodeSrc">The XML source.</param>
/// <param name="TreeNodeXsltSrc">The XSL source.</param>
/// <param name="strOuter">Outer element name.</param>
/// <returns>A new TreeView or null.</returns>
internal TreeView ReadXmlSrc(string TreeNodeSrc, string TreeNodeXsltSrc, string strOuter)
{
XmlTextReader reader;
bool bReading = false;
if (TreeNodeSrc != String.Empty)
{
try
{
reader = GetXmlReaderFromUri(TreeNodeSrc, TreeNodeXsltSrc);
bReading = reader.Read();
}
catch
{
// couldn't read. Try TreeNodeSrc as a string.
reader = GetXmlReaderFromString(TreeNodeSrc, TreeNodeXsltSrc);
if (reader != null)
bReading = reader.Read();
}
if (reader != null && bReading)
{
if (!reader.IsStartElement(strOuter))
{
throw new Exception(String.Format(Util.GetStringResource("TreeMissingOuterContainer"), TreeNodeSrc, TreeNodeXsltSrc));
}
// ParseDesignerModeControl returns a single control (and its children). This is
// a problem if there are multiple top-level treenodes in the XML. Parsing the string
// and finding a matching end tag to each treenode tag is non-trivial.
// For each node, we'd have to handle both
// <TREENODE></TREENODE> and <TREENODE /> cases, and make sure we've got a matched set.
//
// Plan B would be to use XmlTextReader to parse things for us, but it can't handle
// the namespace prefix without a register directive in the page itself.
// *** NOTE: Investigate that possibility.
//
// So, plan C: Add a dummy container treenode, then loop through its children and add
// them to our tree. Simple, effective, and the creation of one extra treenode
// should involve less overhead than lots of text parsing.
string xml = reader.ReadInnerXml();
xml = "<%@ Register TagPrefix='_TreeViewPrefix' Assembly='" + typeof(TreeView).Assembly.ToString() + "' Namespace='Microsoft.Web.UI.WebControls' %><%@ import Namespace='Microsoft.Web.UI.WebControls' %><_TreeViewPrefix:TREEVIEW runat='server'>" + xml + "</_TreeViewPrefix:TREEVIEW>";
Control c = Page.ParseControl(xml);
TreeView tv = (TreeView)c.Controls[0];
return (tv);
}
}
return (null);
}
/// <summary>
/// [TODO: to be supplied]
/// </summary>
/// <param name="TreeNodeSrc">[TODO: to be supplied]</param>
/// <param name="TreeNodeXsltSrc">[TODO: to be supplied]</param>
/// <returns>[TODO: to be supplied]</returns>
internal XmlTextReader GetXmlReaderFromUri(string TreeNodeSrc, string TreeNodeXsltSrc)
{
Uri uri = new Uri(Page.Request.Url, TreeNodeSrc);
if (TreeNodeXsltSrc != String.Empty)
{
// Load TreeNodeSrc into an XmlDocument
XPathDocument xmldoc = new XPathDocument(uri.AbsoluteUri);
return GetXmlReaderFromXPathDoc(xmldoc, TreeNodeXsltSrc);
}
else
{
return new XmlTextReader(uri.AbsoluteUri);
}
}
/// <summary>
/// [TODO: to be supplied]
/// </summary>
/// <param name="TreeNodeSrc">[TODO: to be supplied]</param>
/// <param name="TreeNodeXsltSrc">[TODO: to be supplied]</param>
/// <returns>[TODO: to be supplied]</returns>
internal XmlTextReader GetXmlReaderFromString(string TreeNodeSrc, string TreeNodeXsltSrc)
{
StringReader reader = new StringReader(TreeNodeSrc);
if (TreeNodeXsltSrc != String.Empty)
{
// Load TreeNodeSrc into an XmlDocument
XPathDocument xmldoc = new XPathDocument(reader);
return GetXmlReaderFromXPathDoc(xmldoc, TreeNodeXsltSrc);
}
else
{
return new XmlTextReader(reader);
}
}
/// <summary>
/// [TODO: to be supplied]
/// </summary>
/// <param name="xmldoc">[TODO: to be supplied]</param>
/// <param name="TreeNodeXsltSrc">[TODO: to be supplied]</param>
/// <returns>[TODO: to be supplied]</returns>
internal XmlTextReader GetXmlReaderFromXPathDoc(XPathDocument xmldoc, string TreeNodeXsltSrc)
{
// Load TreeNodeXsltSrc into XslTransform
XslTransform xslTrans = new XslTransform();
Uri uri = new Uri(Page.Request.Url, TreeNodeXsltSrc);
xslTrans.Load(uri.AbsoluteUri);
// Do transform
MemoryStream stream = new MemoryStream();
xslTrans.Transform(((IXPathNavigable)xmldoc).CreateNavigator(), null, stream);
stream.Position = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -