⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tristatetreeview.cs

📁 三态树的开发,可以实现选择的三种状态,分为选中,不选中,其子节点有选中
💻 CS
📖 第 1 页 / 共 2 页
字号:
		/// </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 + -