📄 tristatetreeview.cs
字号:
/// </summary>
/// ------------------------------------------------------------------------------------
[Browsable(false)]
public new int SelectedImageIndex
{
get { return base.SelectedImageIndex; }
set { base.SelectedImageIndex = value; }
}
#endregion
#region Overrides
/// ------------------------------------------------------------------------------------
/// <summary>
/// Called when the user clicks on an item
/// </summary>
/// <param name="e"></param>
/// ------------------------------------------------------------------------------------
protected override void OnClick(EventArgs e)
{
base.OnClick (e);
TV_HITTESTINFO hitTestInfo = new TV_HITTESTINFO();
hitTestInfo.pt = PointToClient(Control.MousePosition);
SendMessage(Handle, TreeViewMessages.TVM_HITTEST,
0, ref hitTestInfo);
if ((hitTestInfo.flags & TVHit.OnItemIcon) == TVHit.OnItemIcon)
{
TreeNode node = GetNodeAt(hitTestInfo.pt);
if (node != null)
ChangeNodeState(node);
}
}
/// ------------------------------------------------------------------------------------
/// <summary>
/// Toggle item if user presses space bar
/// </summary>
/// <param name="e"></param>
/// ------------------------------------------------------------------------------------
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown (e);
if (e.KeyCode == Keys.Space)
ChangeNodeState(SelectedNode);
}
#endregion
#region Private methods
/// ------------------------------------------------------------------------------------
/// <summary>
/// Checks or unchecks all children
/// </summary>
/// <param name="node"></param>
/// <param name="state"></param>
/// ------------------------------------------------------------------------------------
private void CheckNode(TreeNode node, CheckState state)
{
InternalSetChecked(node, state);
foreach (TreeNode child in node.Nodes)
CheckNode(child, state);
}
/// ------------------------------------------------------------------------------------
/// <summary>
/// Called after a node changed its state. Has to go through all direct children and
/// set state based on children's state.
/// </summary>
/// <param name="node">Parent node</param>
/// ------------------------------------------------------------------------------------
private void ChangeParent(TreeNode node)
{
if (node == null)
return;
CheckState state = GetChecked(node.FirstNode);
foreach (TreeNode child in node.Nodes)
state &= GetChecked(child);
if (InternalSetChecked(node, state))
ChangeParent(node.Parent);
}
/// ------------------------------------------------------------------------------------
/// <summary>
/// Handles changing the state of a node
/// </summary>
/// <param name="node"></param>
/// ------------------------------------------------------------------------------------
protected void ChangeNodeState(TreeNode node)
{
BeginUpdate();
CheckState newState;
if (node.ImageIndex == (int)CheckState.Unchecked || node.ImageIndex < 0)
newState = CheckState.Checked;
else
newState = CheckState.Unchecked;
CheckNode(node, newState);
ChangeParent(node.Parent);
EndUpdate();
}
/// ------------------------------------------------------------------------------------
/// <summary>
/// Sets the checked state of a node, but doesn't deal with children or parents
/// </summary>
/// <param name="node">Node</param>
/// <param name="state">The new checked state</param>
/// <returns><c>true</c> if checked state was set to the requested state, otherwise
/// <c>false</c>.</returns>
/// ------------------------------------------------------------------------------------
private bool InternalSetChecked(TreeNode node, CheckState state)
{
TreeViewCancelEventArgs args =
new TreeViewCancelEventArgs(node, false, TreeViewAction.Unknown);
OnBeforeCheck(args);
if (args.Cancel)
return false;
node.ImageIndex = (int)state;
node.SelectedImageIndex = (int)state;
OnAfterCheck(new TreeViewEventArgs(node, TreeViewAction.Unknown));
return true;
}
/// ------------------------------------------------------------------------------------
/// <summary>
/// Build a list of all of the tag data for checked items in the tree.
/// </summary>
/// <param name="node"></param>
/// <param name="list"></param>
/// ------------------------------------------------------------------------------------
private void BuildTagDataList(TreeNode node, ArrayList list)
{
if (GetChecked(node) == CheckState.Checked && node.Tag != null)
list.Add(node.Tag);
foreach (TreeNode child in node.Nodes)
BuildTagDataList(child, list);
}
/// ------------------------------------------------------------------------------------
/// <summary>
/// Look through the tree nodes to find the node that has given tag data and check it.
/// </summary>
/// <param name="node"></param>
/// <param name="tag"></param>
/// <param name="state"></param>
/// ------------------------------------------------------------------------------------
private void FindAndCheckNode(TreeNode node, object tag, CheckState state)
{
if (node.Tag != null && node.Tag.Equals(tag))
{
SetChecked(node, state);
return;
}
foreach (TreeNode child in node.Nodes)
FindAndCheckNode(child, tag, state);
}
#endregion
#region Public methods
/// ------------------------------------------------------------------------------------
/// <summary>
/// Gets the checked state of a node
/// </summary>
/// <param name="node">Node</param>
/// <returns>The checked state</returns>
/// ------------------------------------------------------------------------------------
public CheckState GetChecked(TreeNode node)
{
if (node.ImageIndex < 0)
return CheckState.Unchecked;
else
return (CheckState)node.ImageIndex;
}
/// ------------------------------------------------------------------------------------
/// <summary>
/// Sets the checked state of a node
/// </summary>
/// <param name="node">Node</param>
/// <param name="state">The new checked state</param>
/// ------------------------------------------------------------------------------------
public void SetChecked(TreeNode node, CheckState state)
{
if (!InternalSetChecked(node, state))
return;
CheckNode(node, state);
ChangeParent(node.Parent);
}
/// ------------------------------------------------------------------------------------
/// <summary>
/// Find a node in the tree that matches the given tag data and set its checked state
/// </summary>
/// <param name="tag"></param>
/// <param name="state"></param>
/// ------------------------------------------------------------------------------------
public void CheckNodeByTag(object tag, CheckState state)
{
if (tag == null)
return;
foreach (TreeNode node in Nodes)
FindAndCheckNode(node, tag, state);
}
/// ------------------------------------------------------------------------------------
/// <summary>
/// Return a list of the tag data for all of the checked items in the tree
/// </summary>
/// <returns></returns>
/// ------------------------------------------------------------------------------------
public ArrayList GetCheckedTagData()
{
ArrayList list = new ArrayList();
foreach (TreeNode node in Nodes)
BuildTagDataList(node, list);
return list;
}
#endregion
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -