支持三态的TreeView控件

.Net framework提供了TreeView 控件,但该控件不支持三态的形式。所谓三态就是带CheckBox的TreeView每个Node都有三种状态,即选中,未选中和部分选中(指该Node的字节点并非全部选中)。

    我做了一个支持这种功能的控件:TriStateTreeView。如下图所示:

     

     该控件支持三态的TreeView,并且支持当某个节点的Checkbox 状态发生改变时,自动回溯子节点和父节点。

     使用该控件需要注意的是,必须使用AddTreeNode方法增加Node. 不能用Nodes.Add来增加。

     该控件还提供了下面两个方法来获取和设置Node的Checkbox 状态:GetTreeNodeCheckBoxChecked,SetTreeNodeCheckBoxChecked

     当Checkbox状态发生改变时,该控件提供一个 CheckBoxStateChanged  事件来截获状态的变化。

     如果你觉得Checkbox 的图形不好看,你可以通过 CheckBoxStateImageList 属性来修改Checkbox 的图形

     下载位置: V1.0.0.4 Source Code

      关键技术:

      本控件是通过改变Node 对应的Checkbox的图形来实现三种状态显示不同的Checkbox 边框的。在CheckBoxStateImageList这个ImageList中存放了4个图标,分别显示空状态,选中状态,未选中状态和部分选中状态的图形。由于TreeView控件没有封装修改CheckBox图形的方法,本控件通过向TreeView发生一个Windows 消息来修改控件的图形:

      修改方法见下面代码:

   

         ///   <summary>
        
///  Set tree node checkbox state
        
///   </summary>
        
///   <param name="treeNode"> tree node </param>
        
///   <param name="checkboxState"> checkbox state </param>
         private   void  SetTreeNodeState(TreeNode treeNode, CheckBoxState checkboxState)
        {
            IntPtr hWnd;
            TVITEM tvi;
            hWnd 
=   this .Handle;

            
//  Send a TVM_SETIMAGELIST with TVSIL_STATE.
             if  ( ! _ImageListSent)
            {

                SendMessage(hWnd, (UInt32)TVM_SETIMAGELIST, (UInt32)TVSIL_STATE, 

(UInt32)CheckBoxStateImageList.Handle);

 

                _ImageListSent  =   true ;
            }

            
//  The following uses the TVM_SETITEM message to set the State 
            
//  of a given item. It uses the TVITEM structure.

            
//   tvi.mask: include TVIF_HANDLE and TVIF_STATE
            tvi.mask  =  TVIF_HANDLE  |  TVIF_STATE;

            
//  To use the State image, tvi.State cannot be 0.  
            
// Setting it to 1 means to use the second image in the image list.
            tvi.state  =  ( uint )checkboxState;
            
//  Left shift 12 to put info in bits 12 to 15
            tvi.state  =  tvi.state  <<   12 ;
            
//  Set StateMask. -This is required to isolate State above.
            tvi.stateMask  =  TVIS_STATEIMAGEMASK;

            
//  Define the item we want to set the State in.
            tvi.hItem  =  treeNode.Handle;   // For example, try the root.

            
//   Initialize the rest to zero.
            tvi.pszText  =  (IntPtr) 0 ;
            tvi.cchTextMax 
=   0 ;
            tvi.iImage 
=   0 ;
            tvi.iSelectedImage 
=   0 ;
            tvi.cChildren 
=   0 ;
            tvi.lParam 
=  (IntPtr) 0 ;

            
//  Send the TVM_SETITEM message.
            
//   TVM_SETITEM = 4365
            SendMessage(hWnd, (UInt32)TVM_SETITEM, (UInt32) 0 ref  tvi);

            
// Set Node State
            SetNodeState(treeNode, checkboxState);
        }


 

首先需要发送 TVM_SETIMAGELIST 通知TreeView CheckBox 使用的ImageList。然后发送 TVM_SETITEM 来设置CheckBox 对应的图形。

知道了这个方法,其他实现起来就比较简单了,这里不再多说。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值