xenadmin/XenAdmin/Controls/TreeViews/VirtualTreeView.cs
Gabor Apati-Nagy 7c0bc50b4a CA-176169: Changed copyright statements to include the comma in Citrix Systems,
Inc.

Signed-off-by: Gabor Apati-Nagy<gabor.apati-nagy@citrix.com>
2017-01-16 19:59:50 +00:00

939 lines
30 KiB
C#

/* Copyright (c) Citrix Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* * Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
using System.Collections.Generic;
using System.Windows.Forms;
using System.ComponentModel;
using System;
using System.Drawing;
using System.Diagnostics;
using System.Collections.ObjectModel;
namespace XenAdmin.Controls
{
/// <summary>
/// A <see cref="TreeView"/> that only adds <see cref="TreeNode"/>s when they become visible.
/// </summary>
public partial class VirtualTreeView : MultiSelectTreeView, IVirtualTreeNodeCollectionOwner, IHaveNodes
{
private readonly VirtualTreeNodeCollection _nodes;
private readonly VirtualTreeSelectedNodeCollection _selectedNodes;
/// <summary>
/// Initializes a new instance of the <see cref="VirtualTreeView"/> class.
/// </summary>
public VirtualTreeView()
{
_nodes = new VirtualTreeNodeCollection(this);
_selectedNodes = new VirtualTreeSelectedNodeCollection(this);
}
/// <summary>
/// Gets or sets the tree node that is currently selected in the tree view control.
/// </summary>
/// <value></value>
/// <returns>
/// The <see cref="VirtualTreeNode"/> that is currently selected in the tree view control.
/// </returns>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Browsable(false)]
public new VirtualTreeNode SelectedNode
{
get
{
return (VirtualTreeNode)base.SelectedNode;
}
set
{
if (value != null)
{
Devirtualise(value);
}
base.SelectedNode = value;
}
}
/// <summary>
/// Gets or sets the first fully-visible tree node in the tree view control.
/// </summary>
/// <value></value>
/// <returns>
/// A <see cref="VirtualTreeNode"/> that represents the first fully-visible tree node in the tree view control.
/// </returns>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Browsable(false)]
public new VirtualTreeNode TopNode
{
get { return (VirtualTreeNode)base.TopNode; }
set
{
Util.ThrowIfParameterNull(value, "value");
Devirtualise(value);
base.TopNode = value;
}
}
private static List<VirtualTreeNode> GetParents(VirtualTreeNode node)
{
List<VirtualTreeNode> parents = new List<VirtualTreeNode>();
VirtualTreeNode nn = node.Parent;
while (nn != null)
{
parents.Add(nn);
nn = nn.Parent;
}
parents.Reverse();
return parents;
}
/// <summary>
/// Populates the real nodes for every node from the root down to this node.
/// </summary>
private void Devirtualise(VirtualTreeNode node)
{
foreach (VirtualTreeNode parent in GetParents(node))
{
Devirtualise(parent.Nodes);
}
}
/// <summary>
/// Ensures that all real nodes are up-to-date with the virtual ones.
/// </summary>
private void Devirtualise(VirtualTreeNodeCollection nodes)
{
if (NodeCollectionRequiresUpdate(nodes.Owner))
{
nodes.Owner.RealNodes.Clear();
nodes.Owner.RealNodes.AddRange(new List<VirtualTreeNode>(nodes).ToArray());
}
}
private static bool NodeCollectionRequiresUpdate(IVirtualTreeNodeCollectionOwner owner)
{
if (owner.RealNodes.Count == 1 && owner.RealNodes[0] is DummyTreeNode)
{
return true;
}
if (owner.RealNodes.Count != owner.Nodes.Count)
{
return true;
}
for (int i = 0; i < owner.Nodes.Count; i++)
{
if (owner.RealNodes[i] != owner.Nodes[i])
{
return true;
}
}
return false;
}
public new VirtualTreeSelectedNodeCollection SelectedNodes
{
get { return _selectedNodes; }
}
#region IVirtualTreeNodeCollectionOwner Members
public new VirtualTreeNodeCollection Nodes
{
get { return _nodes; }
}
MultiSelectTreeNodeCollection IVirtualTreeNodeCollectionOwner.RealNodes
{
get { return base.Nodes; }
}
#endregion
#region IHaveNodes Members
VirtualTreeView.VirtualTreeNodeCollection IHaveNodes.Nodes
{
get { return Nodes; }
}
object IHaveNodes.Tag
{
get { return Tag; }
}
void IHaveNodes.Expand()
{
}
void IHaveNodes.Collapse()
{
}
#endregion
/// <summary>
/// Retrieves the tree node that is at the specified point.
/// </summary>
public new VirtualTreeNode GetNodeAt(Point pt)
{
return (VirtualTreeNode)base.GetNodeAt(pt);
}
/// <summary>
/// Retrieves the tree node that is at the specified point.
/// </summary>
public new VirtualTreeNode GetNodeAt(int x, int y)
{
return (VirtualTreeNode)base.GetNodeAt(x, y);
}
/// <summary>
/// Merges the specified node tree with the existing one. Automatically does a BeginUpdate
/// if the nodes change.
/// </summary>
/// <param name="newRootNodes">The new root nodes.</param>
public void UpdateRootNodes(IEnumerable<VirtualTreeNode> newRootNodes)
{
Util.ThrowIfParameterNull(newRootNodes, "newRootNodes");
foreach (VirtualTreeNode node in newRootNodes)
{
if (node.TreeView != null)
{
throw new ArgumentException("newRootNodes should not be attached to a TreeView.", "newRootNodes");
}
}
bool doneBeginUpdate = false;
UpdateNodes(Nodes, new List<VirtualTreeNode>(newRootNodes), ref doneBeginUpdate);
}
private void UpdateNodes(VirtualTreeNodeCollection oldNodes, IList<VirtualTreeNode> newNodes, ref bool doneBeginUpdate)
{
for (int i = 0; i < Math.Max(oldNodes.Count, newNodes.Count); )
{
if (oldNodes.Count > i && newNodes.Count > i)
{
if (oldNodes[i].Nodes.Count > 0 && newNodes[i].Nodes.Count == 0 && oldNodes[i].IsExpanded)
{
// fix for issues CA-34486 and CA-36409
// see VirtualTreeViewTests.TestUpdateWhenRemoveAllChildNodesOfExandedParent
// When merging sets of tree-nodes using UpdateRootNodes, if you remove all of
// the child-nodes from a node, the node still remembers its IsExpanded state
// from before the nodes were removed regardless of whether you call Collapse()
// or Expand() after the nodes were removed.
// This causes problems for the Virtual treeview as it
// relies the BeforeExpanded event to convert DummyTreeNodes into VirtualTreeNodes
// on population.
oldNodes[i].Collapse();
}
UpdateNode(newNodes[i], oldNodes[i], ref doneBeginUpdate);
UpdateNodes(oldNodes[i].Nodes, newNodes[i].Nodes, ref doneBeginUpdate);
i++;
}
else if (oldNodes.Count <= i && newNodes.Count > i)
{
LogTreeView("Adding node " + newNodes[i].Text);
DoBeginUpdateIfRequired(ref doneBeginUpdate);
oldNodes.Add(newNodes[i]);
UpdateNodes(oldNodes[i].Nodes, newNodes[i].Nodes, ref doneBeginUpdate);
i++;
}
else
{
LogTreeView("Removing node " + oldNodes[i].Text);
DoBeginUpdateIfRequired(ref doneBeginUpdate);
oldNodes.RemoveAt(i);
}
}
}
private void DoBeginUpdateIfRequired(ref bool doneBeginUpdate)
{
if (!doneBeginUpdate)
{
doneBeginUpdate = true;
BeginUpdate();
}
}
[Conditional("DEBUG")]
private void LogTreeView(string s)
{
//Debug.WriteLine(s);
}
private void UpdateNode(VirtualTreeNode src, VirtualTreeNode dest, ref bool doneBeginUpdate)
{
if (dest.ImageIndex != src.ImageIndex)
{
DoBeginUpdateIfRequired(ref doneBeginUpdate);
dest.ImageIndex = src.ImageIndex;
}
if (dest.SelectedImageIndex != src.SelectedImageIndex)
{
DoBeginUpdateIfRequired(ref doneBeginUpdate);
dest.SelectedImageIndex = src.SelectedImageIndex;
}
if (dest.Text != src.Text)
{
LogTreeView("Overwriting " + src.Text + " with " + dest.Text);
DoBeginUpdateIfRequired(ref doneBeginUpdate);
dest.Text = src.Text;
}
if (dest.Tag != src.Tag)
{
dest.Tag = src.Tag;
}
if (dest.NodeFont != src.NodeFont)
{
DoBeginUpdateIfRequired(ref doneBeginUpdate);
dest.NodeFont = src.NodeFont;
}
if (dest.BackColor != src.BackColor)
{
DoBeginUpdateIfRequired(ref doneBeginUpdate);
dest.BackColor = src.BackColor;
}
if (dest.ForeColor != src.ForeColor)
{
DoBeginUpdateIfRequired(ref doneBeginUpdate);
dest.ForeColor = src.ForeColor;
}
if (dest.Name != src.Name)
{
DoBeginUpdateIfRequired(ref doneBeginUpdate);
dest.Name = src.Name;
}
if (dest.ShowCheckBox != src.ShowCheckBox)
{
DoBeginUpdateIfRequired(ref doneBeginUpdate);
dest.ShowCheckBox = src.ShowCheckBox;
}
if (dest.Checked != src.Checked)
{
DoBeginUpdateIfRequired(ref doneBeginUpdate);
dest.Checked = src.Checked;
}
}
/// <summary>
/// Iterates through every node of this <see cref="VirtualTreeView"/>.
/// </summary>
public new IEnumerable<VirtualTreeNode> AllNodes
{
get
{
foreach (VirtualTreeNode node in Nodes)
{
yield return node;
foreach (VirtualTreeNode n in node.Descendants)
{
yield return n;
}
}
}
}
#region Virtual overrides
protected sealed override void OnAfterCheck(TreeViewEventArgs e)
{
VirtualTreeNode node = (VirtualTreeNode)e.Node;
OnAfterCheck(new VirtualTreeViewEventArgs(node, e.Action));
}
protected sealed override void OnBeforeCheck(TreeViewCancelEventArgs e)
{
VirtualTreeNode node = (VirtualTreeNode)e.Node;
VirtualTreeViewCancelEventArgs args = new VirtualTreeViewCancelEventArgs(node, e.Cancel, e.Action);
OnBeforeCheck(args);
e.Cancel = args.Cancel;
}
protected sealed override void OnAfterCollapse(TreeViewEventArgs e)
{
VirtualTreeNode node = (VirtualTreeNode)e.Node;
OnAfterCollapse(new VirtualTreeViewEventArgs(node, e.Action));
}
protected sealed override void OnBeforeCollapse(TreeViewCancelEventArgs e)
{
VirtualTreeNode node = (VirtualTreeNode)e.Node;
VirtualTreeViewCancelEventArgs args = new VirtualTreeViewCancelEventArgs(node, e.Cancel, e.Action);
OnBeforeCollapse(args);
e.Cancel = args.Cancel;
}
protected sealed override void OnAfterExpand(TreeViewEventArgs e)
{
VirtualTreeNode node = (VirtualTreeNode)e.Node;
OnAfterExpand(new VirtualTreeViewEventArgs(node, e.Action));
}
protected sealed override void OnBeforeExpand(TreeViewCancelEventArgs e)
{
VirtualTreeNode node = (VirtualTreeNode)e.Node;
Devirtualise(node.Nodes);
VirtualTreeViewCancelEventArgs args = new VirtualTreeViewCancelEventArgs(node, e.Cancel, e.Action);
OnBeforeExpand(args);
e.Cancel = args.Cancel;
}
protected sealed override void OnAfterDeselect(TreeViewEventArgs e)
{
VirtualTreeNode node = (VirtualTreeNode)e.Node;
OnAfterDeselect(new VirtualTreeViewEventArgs(node));
}
protected sealed override void OnBeforeDeselect(TreeViewEventArgs e)
{
VirtualTreeNode node = (VirtualTreeNode)e.Node;
OnBeforeDeselect(new VirtualTreeViewEventArgs(node));
}
protected sealed override void OnAfterSelect(TreeViewEventArgs e)
{
VirtualTreeNode node = (VirtualTreeNode)e.Node;
OnAfterSelect(new VirtualTreeViewEventArgs(node, e.Action));
}
protected sealed override void OnBeforeSelect(MultiSelectTreeViewCancelEventArgs e)
{
VirtualTreeNode node = (VirtualTreeNode)e.Node;
VirtualTreeViewCancelEventArgs args = new VirtualTreeViewCancelEventArgs(node, e.Cancel, e.Action);
OnBeforeSelect(args);
e.Cancel = args.Cancel;
}
protected sealed override void OnNodeMouseClick(TreeNodeMouseClickEventArgs e)
{
VirtualTreeNode node = (VirtualTreeNode)e.Node;
OnNodeMouseClick(new VirtualTreeNodeMouseClickEventArgs(node, e.Button, e.Clicks, e.X, e.Y));
}
protected sealed override void OnNodeMouseDoubleClick(TreeNodeMouseClickEventArgs e)
{
VirtualTreeNode node = (VirtualTreeNode)e.Node;
OnNodeMouseDoubleClick(new VirtualTreeNodeMouseClickEventArgs(node, e.Button, e.Clicks, e.X, e.Y));
}
protected sealed override void OnAfterLabelEdit(NodeLabelEditEventArgs e)
{
VirtualTreeNode node = (VirtualTreeNode)e.Node;
VirtualNodeLabelEditEventArgs args = new VirtualNodeLabelEditEventArgs(node, e.Label);
OnAfterLabelEdit(args);
e.CancelEdit = args.CancelEdit;
}
protected sealed override void OnBeforeLabelEdit(NodeLabelEditEventArgs e)
{
VirtualTreeNode node = (VirtualTreeNode)e.Node;
VirtualNodeLabelEditEventArgs args = new VirtualNodeLabelEditEventArgs(node, e.Label);
OnBeforeLabelEdit(args);
e.CancelEdit = args.CancelEdit;
}
protected sealed override void OnItemDrag(MultiSelectTreeViewItemDragEventArgs e)
{
List<VirtualTreeNode> nodes = new List<VirtualTreeNode>();
foreach (MultiSelectTreeNode n in e.Nodes)
{
nodes.Add((VirtualTreeNode)n);
}
OnItemDrag(new VirtualTreeViewItemDragEventArgs(e.Button, nodes));
}
protected virtual void OnAfterCheck(VirtualTreeViewEventArgs e)
{
EventHandler<VirtualTreeViewEventArgs> handler = AfterCheck;
if (handler != null)
{
handler(this, e);
}
}
protected virtual void OnBeforeCheck(VirtualTreeViewCancelEventArgs e)
{
EventHandler<VirtualTreeViewCancelEventArgs> handler = BeforeCheck;
if (handler != null)
{
handler(this, e);
}
}
protected virtual void OnAfterCollapse(VirtualTreeViewEventArgs e)
{
EventHandler<VirtualTreeViewEventArgs> handler = AfterCollapse;
if (handler != null)
{
handler(this, e);
}
}
protected virtual void OnBeforeCollapse(VirtualTreeViewCancelEventArgs e)
{
EventHandler<VirtualTreeViewCancelEventArgs> handler = BeforeCollapse;
if (handler != null)
{
handler(this, e);
}
}
protected virtual void OnAfterExpand(VirtualTreeViewEventArgs e)
{
EventHandler<VirtualTreeViewEventArgs> handler = AfterExpand;
if (handler != null)
{
handler(this, e);
}
}
protected virtual void OnBeforeExpand(VirtualTreeViewCancelEventArgs e)
{
EventHandler<VirtualTreeViewCancelEventArgs> handler = BeforeExpand;
if (handler != null)
{
handler(this, e);
}
}
protected virtual void OnAfterDeselect(VirtualTreeViewEventArgs e)
{
EventHandler<VirtualTreeViewEventArgs> handler = AfterDeselect;
if (handler != null)
{
handler(this, e);
}
}
protected virtual void OnBeforeDeselect(VirtualTreeViewEventArgs e)
{
EventHandler<VirtualTreeViewEventArgs> handler = BeforeDeselect;
if (handler != null)
{
handler(this, e);
}
}
protected virtual void OnAfterSelect(VirtualTreeViewEventArgs e)
{
EventHandler<VirtualTreeViewEventArgs> handler = AfterSelect;
if (handler != null)
{
handler(this, e);
}
}
protected virtual void OnBeforeSelect(VirtualTreeViewCancelEventArgs e)
{
EventHandler<VirtualTreeViewCancelEventArgs> handler = BeforeSelect;
if (handler != null)
{
handler(this, e);
}
}
protected virtual void OnBeforeLabelEdit(VirtualNodeLabelEditEventArgs e)
{
EventHandler<VirtualNodeLabelEditEventArgs> handler = BeforeLabelEdit;
if (handler != null)
{
handler(this, e);
}
}
protected virtual void OnAfterLabelEdit(VirtualNodeLabelEditEventArgs e)
{
EventHandler<VirtualNodeLabelEditEventArgs> handler = AfterLabelEdit;
if (handler != null)
{
handler(this, e);
}
}
protected virtual void OnNodeMouseClick(VirtualTreeNodeMouseClickEventArgs e)
{
EventHandler<VirtualTreeNodeMouseClickEventArgs> handler = NodeMouseClick;
if (handler != null)
{
handler(this, e);
}
}
protected virtual void OnNodeMouseDoubleClick(VirtualTreeNodeMouseClickEventArgs e)
{
EventHandler<VirtualTreeNodeMouseClickEventArgs> handler = NodeMouseDoubleClick;
if (handler != null)
{
handler(this, e);
}
}
protected virtual void OnItemDrag(VirtualTreeViewItemDragEventArgs e)
{
EventHandler<VirtualTreeViewItemDragEventArgs> handler = ItemDrag;
if (handler != null)
{
handler(this, e);
}
}
#endregion
#region Events
/// <summary>
/// Occurs after the tree node check box is checked.
/// </summary>
[Category("Behavior"), Description("Occurs after the tree node check box is checked.")]
public new event EventHandler<VirtualTreeViewEventArgs> AfterCheck;
/// <summary>
/// Occurs before the tree node check box is checked.
/// </summary>
[Category("Behavior"), Description("Occurs before the tree node check box is checked.")]
public new event EventHandler<VirtualTreeViewCancelEventArgs> BeforeCheck;
/// <summary>
/// Occurs after the tree node is collapsed.
/// </summary>
[Category("Behavior"), Description("Occurs after the tree node is collapsed.")]
public new event EventHandler<VirtualTreeViewEventArgs> AfterCollapse;
/// <summary>
/// Occurs before the tree node is collapsed.
/// </summary>
[Category("Behavior"), Description("Occurs before the tree node is collapsed.")]
public new event EventHandler<VirtualTreeViewCancelEventArgs> BeforeCollapse;
/// <summary>
/// Occurs after the tree node is expanded.
/// </summary>
[Category("Behavior"), Description("Occurs after the tree node is expanded.")]
public new event EventHandler<VirtualTreeViewEventArgs> AfterExpand;
/// <summary>
/// Occurs before the tree node is expanded.
/// </summary>
[Category("Behavior"), Description("Occurs after the tree node is expanded.")]
public new event EventHandler<VirtualTreeViewCancelEventArgs> BeforeExpand;
/// <summary>
/// Occurs after the tree node is deselected.
/// </summary>
[Category("Behavior"), Description("Occurs after the tree node is deselected.")]
public new event EventHandler<VirtualTreeViewEventArgs> AfterDeselect;
/// <summary>
/// Occurs before the tree node is deselected.
/// </summary>
[Category("Behavior"), Description("Occurs after the tree node is deselected.")]
public new event EventHandler<VirtualTreeViewEventArgs> BeforeDeselect;
/// <summary>
/// Occurs after the tree node is selected.
/// </summary>
[Category("Behavior"), Description("Occurs after the tree node is selected.")]
public new event EventHandler<VirtualTreeViewEventArgs> AfterSelect;
/// <summary>
/// Occurs before the tree node is selected.
/// </summary>
[Category("Behavior"), Description("Occurs before the tree node is selected.")]
public new event EventHandler<VirtualTreeViewCancelEventArgs> BeforeSelect;
/// <summary>
/// Occurs after the node is clicked.
/// </summary>
[Category("Behavior"), Description("Occurs after the node is clicked.")]
public new event EventHandler<VirtualTreeNodeMouseClickEventArgs> NodeMouseClick;
/// <summary>
/// Occurs after the node is double clicked.
/// </summary>
[Category("Behavior"), Description("Occurs after the node is double clicked.")]
public new event EventHandler<VirtualTreeNodeMouseClickEventArgs> NodeMouseDoubleClick;
/// <summary>
/// Occurs after the tree node label is edited.
/// </summary>
[Category("Behavior"), Description("Occurs after the tree node label is edited.")]
public new event EventHandler<VirtualNodeLabelEditEventArgs> AfterLabelEdit;
/// <summary>
/// Occurs before the tree node label is edited.
/// </summary>
[Category("Behavior"), Description("Occurs before the tree node label is edited.")]
public new event EventHandler<VirtualNodeLabelEditEventArgs> BeforeLabelEdit;
/// <summary>
/// Occurs when a node starts being dragged.
/// </summary>
[Category("Behavior"), Description("Occurs when a node starts being dragged.")]
public new event EventHandler<VirtualTreeViewItemDragEventArgs> ItemDrag;
#endregion
/// <summary>
/// Used to ensure that the '+' expander thingy is visible when a node has children.
/// </summary>
private class DummyTreeNode : MultiSelectTreeNode
{
}
}
internal interface IVirtualTreeNodeCollectionOwner
{
/// <summary>
/// Gets a complete collection of nodes owned.
/// </summary>
VirtualTreeView.VirtualTreeNodeCollection Nodes { get;}
/// <summary>
/// Gets a collection of the nodes which are actually added to the base <see cref="System.Windows.Forms.TreeView"/>.
/// </summary>
MultiSelectTreeNodeCollection RealNodes { get;}
}
internal interface IHaveNodes
{
VirtualTreeView.VirtualTreeNodeCollection Nodes { get; }
object Tag { get; }
void Expand();
void Collapse();
}
#region VirtualTreeView EventArgs classes
public class VirtualTreeViewEventArgs : EventArgs
{
private readonly TreeViewAction _action;
private readonly VirtualTreeNode _node;
public VirtualTreeViewEventArgs(VirtualTreeNode node)
{
Util.ThrowIfParameterNull(node, "node");
_node = node;
}
public VirtualTreeViewEventArgs(VirtualTreeNode node, TreeViewAction action)
: this(node)
{
_action = action;
}
public TreeViewAction Action
{
get
{
return _action;
}
}
public VirtualTreeNode Node
{
get
{
return _node;
}
}
}
public class VirtualTreeViewCancelEventArgs : CancelEventArgs
{
private readonly TreeViewAction _action;
private readonly VirtualTreeNode _node;
public VirtualTreeViewCancelEventArgs(VirtualTreeNode node, bool cancel, TreeViewAction action)
: base(cancel)
{
_node = node;
_action = action;
}
public TreeViewAction Action
{
get
{
return _action;
}
}
public VirtualTreeNode Node
{
get
{
return _node;
}
}
}
public class VirtualTreeNodeMouseClickEventArgs : MouseEventArgs
{
private readonly VirtualTreeNode _node;
public VirtualTreeNodeMouseClickEventArgs(VirtualTreeNode node, MouseButtons button, int clicks, int x, int y)
: base(button , clicks , x , y, 0)
{
_node = node;
}
public VirtualTreeNode Node
{
get
{
return _node;
}
}
}
public class VirtualNodeLabelEditEventArgs : EventArgs
{
private bool _cancelEdit;
private readonly string _label;
private readonly VirtualTreeNode _node;
public VirtualNodeLabelEditEventArgs(VirtualTreeNode node)
{
Util.ThrowIfParameterNull(node, "node");
_node = node;
_label = null;
}
public VirtualNodeLabelEditEventArgs(VirtualTreeNode node, string label)
: this(node)
{
_label = label;
}
public bool CancelEdit
{
get
{
return _cancelEdit;
}
set
{
_cancelEdit = value;
}
}
public string Label
{
get
{
return _label;
}
}
public VirtualTreeNode Node
{
get
{
return _node;
}
}
}
public class VirtualTreeViewItemDragEventArgs : EventArgs
{
private readonly ReadOnlyCollection<VirtualTreeNode> _nodes;
private readonly MouseButtons _button;
public VirtualTreeViewItemDragEventArgs(MouseButtons button)
: this(button, new VirtualTreeNode[0])
{
}
public VirtualTreeViewItemDragEventArgs(MouseButtons button, IEnumerable<VirtualTreeNode> nodes)
{
_nodes = new ReadOnlyCollection<VirtualTreeNode>(new List<VirtualTreeNode>(nodes));
_button = button;
}
public MouseButtons Button
{
get
{
return _button;
}
}
public ReadOnlyCollection<VirtualTreeNode> Nodes
{
get
{
return _nodes;
}
}
}
#endregion
}