解决 WinForm 中 TreeView 的 StateImageList 实际显示大小无法改变的问题 及 TreeView其他问题

一、解决 WinForm 中 TreeView 的 StateImageList 实际显示大小无法改变的问题

来自:http://blog.csdn.net/lethwei/article/details/4334728

因为项目需要, 要更改 TreeView 的 StateImageList 大小, 试了下, 更改绑定的 StateImageList.ImageSize 没有作用, 显示大小始终是 16x16

在网上搜了搜, 相关资料比较少, 终于在 CodeProject 上找到问题原因:

http://www.codeproject.com/KB/tree/customstatetreeview.aspx?display=PrintAll&fid=313614&df=90&mpp=25&noise=3&sort=Position&view=Quick&select=1519145


附文:

Underlying comctl treeview uses a zero image index, indicating no state image is displayed.
Thus comctl state imagelist must have a dummy as first image.
.NET copies the passed StateImageList to a new NET internal imagelist.
The first image is duplicated, serving as dummy and the copy is passed to comctl.
TreeNode.StateImageIndex values passed to comctl are then increased by 1.
This might have been a nice feature, but WinForms Team blundered using a constant 16 x 16 size for the copy.
If you want different size, use code below and add a dummy as first image.


创建组件类,继承TreeView 代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
//
using System.Windows.Forms;

namespace WinControl
{
    public partial class TreeViewImageStatusUser : TreeView
    {
        public TreeViewImageStatusUser()
        {
            InitializeComponent();
        }

        public TreeViewImageStatusUser(IContainer container)
        {
            container.Add(this);

            InitializeComponent();
        }
        protected override void WndProc(ref Message m)
        {
            const int TV_FIRST = 0x1100;
            const int TVM_SETIMAGELIST = (TV_FIRST + 9);
            const int TVSIL_STATE = 2;

            if (m.Msg == TVM_SETIMAGELIST)
            {
                if (m.WParam.ToInt32() == TVSIL_STATE &&
                m.LParam != IntPtr.Zero)
                {
                    // NET assigns a copy of StateImageList
                    Debug.Assert(StateImageList != null);
                    // pass comctl the original
                    m.LParam = StateImageList.Handle;
                }
            }

            base.WndProc(ref m);
        }
    }
}



使用:

                tvDept.CheckBoxes = true;
                tvDept.ImageList = imglDep;
                tvDept.StateImageList = imglDepC;
               //绑定TreeView的数据 Classes.Common.CreateTreeView(tvDept.Nodes, Ds, 0, "UpDepID", "Name", "ID");
                tvDept.ExpandAll();


记得在imglDepC中有3个图片,第一个是个24X24的空图片,然后是checkbox的两个状态

我在做的24X24 的图片,有2px的空白边,这样,上下两个Checkbox就不会完全相贴着。




二、TreeView 子节点checkbox状态与父节点相同

来自:http://msdn.microsoft.com/zh-cn/magazine/system.windows.forms.treeview.beforecheck(de-de,VS.80).aspx

        #region 点击节点Checkbox子节点都同父节点
        private void CheckAllChildNodes(TreeNode treeNode, bool nodeChecked)
        {
            foreach (TreeNode node in treeNode.Nodes)
            {
                node.Checked = nodeChecked;
                if (node.Nodes.Count > 0)
                {
                    // If the current node has child nodes, call the CheckAllChildsNodes method recursively.
                    this.CheckAllChildNodes(node, nodeChecked);
                }
            }
        }

        private void TreeView_AfterCheck(object sender, TreeViewEventArgs e)
        {
            // The code only executes if the user caused the checked state to change.
            if (e.Action != TreeViewAction.Unknown)
            {
                if (e.Node.Nodes.Count > 0)
                {
                    /* Calls the CheckAllChildNodes method, passing in the current 
                    Checked value of the TreeNode whose checked state changed. */
                    CheckAllChildNodes(e.Node, e.Node.Checked);
                }
            }

        }        
        #endregion 点击节点Checkbox子节点都同父节点



你可能感兴趣的:(WinForm,C#,WinForm自定义控件)