日期:2014-05-18  浏览次数:21004 次

求重写TreeView的CheckBoxes实现第三种状态(有部分子节点选中)
我在参考了这里,确实实现了第三种状态,但是点击某行的任意位置都会触发该节点状态改变,所以不想用这种方法。现希望各位大虾给出通过重写TreeView的办法来实现当部分子结点被选中时父节点有第三种状态的详细代码。

------解决方案--------------------
示例代码在5楼:
http://topic.csdn.net/u/20080529/18/304A8BE8-F534-4CC4-921E-BD9E3E9E1969.html
------解决方案--------------------
C# code
 /// <summary>
        /// 获取某个节点的状态。
        /// </summary>
        /// <param name="node">要获取状态的节点</param>
        /// <returns>当前节点的状态</returns>

        //***********************************************************
        //*     函数名称:GetChecked
        //*     功能描述:获取当前节点的状态
        //*     参    数:无
        //*     返 回 值:
        //*     作    者:
        //*     创建日期:2004-06-28
        //***********************************************************
        public EnumCheckState GetChecked(TreeNode node)
        {
            TVITEM tTVITEM = new TVITEM();
            int iState;
            int iResult;
            tTVITEM.mask = (int)(TVHit.OnItemButton | TVHit.OnItemIndent);
            tTVITEM.hItem = node.Handle;
            tTVITEM.stateMask = (int)(TVHit.TVIS_STATEIMAGEMASK);
            tTVITEM.state = 0;

            iResult = SendMessage(this.Handle, TreeViewMessages.TVM_GETITEM, 0, ref tTVITEM);
            if (iResult != 0)
            {
                iState = tTVITEM.state;
                iState = iState / 0xFFF;

                return (EnumCheckState)(iState);
            }
            else
            {
                return EnumCheckState.Unchecked;
            }
        }

        /// <summary>
        /// 设置节点状态。
        /// </summary>
        /// <param name="node">要设置的节点</param>
        /// <param name="state">设置的状态</param>
        //***********************************************************
        //*     函数名称:SetChecked
        //*     功能描述:设置节点的状态
        //*     参    数:无
        //*     返 回 值:
        //*     作    者:
        //*     创建日期:2004-06-28
        //***********************************************************
        public void SetChecked(TreeNode node, EnumCheckState state)
        {
            CheckNode(node, state);
            if (m_bThreeState && !m_bRadioCheck)
            {
                ChangeParent(node.Parent);
            }
        }

        /// <summary>
        /// 设置一个节点的状态,且当前节点的父节点和子节点状态不改变。
        /// </summary>
        /// <param name="node">要设置的节点</param>
        /// <param name="state">设置的状态</param>
        //***********************************************************
        //*     函数名称:SetInternalChecked
        //*     功能描述:改变当前节点的状态
        //*     参    数:无
        //*     返 回 值:
        //*     作    者:
        //*     创建日期:2004-06-28
        //***********************************************************
        public void SetInternalChecked(TreeNode node, EnumCheckState state)
        {
            int iState = (int)state;

            TVITEM tTVITEM = new TVITEM();
            tTVITEM.mask = (int)(TVHit.OnItemButton | TVHit.OnItemIndent);
            tTVITEM.hItem = node.Handle;
            tTVITEM.stateMask = (int)TVHit.TVIS_STATEIMAGEMASK;
            tTVITEM.state = iState * 0x1000;

            SendMessage(this.Handle, TreeViewMessages.TVM_SETITEM, 0, ref tTVITEM);

            base.OnAfterCheck(new System.Windows.Forms.TreeViewEventArgs(node));
        }


        #endregion

        #region "重写方法"
        /// <summary>
        /// 重写控件的 Refresh 方法,重绘控件
        /// </summary>
        //***********************************************************
        //*     函数名称:Refresh
        //*     功能描述:重写Refresh方法
        //*     参    数:无
        //*     返 回 值:
        //*     作    者:
        //*     创建日期:2004-06-28
        //**********************************************