C# 允许在.NET树视图中进行多选

C# 允许在.NET树视图中进行多选,c#,.net,winforms,.net-2.0,treeview,C#,.net,Winforms,.net 2.0,Treeview,我被困在.NET2.0Windows窗体中 标准TreeView控件中似乎不存在选择多个节点的功能 我正在尝试为上下文菜单选择这样做。因此,复选框在这里不是一个可接受的UI范例 提供这种非常必要的功能的最佳方式是什么?复选框是选项吗?还是要像列表框中一样选择 复选框是内置的 像在列表框中一样选择需要自定义树控件 CodeProject上提供了一个多选树控件:我们曾经在WTL项目中这样做过一次,但所需的基本工作与.NET相同。要实现多选树控件,您需要自己绘制树项并覆盖键盘和鼠标处理。您还需要维

我被困在.NET2.0Windows窗体中

标准
TreeView
控件中似乎不存在选择多个节点的功能

我正在尝试为上下文菜单选择这样做。因此,复选框在这里不是一个可接受的UI范例


提供这种非常必要的功能的最佳方式是什么?

复选框是选项吗?还是要像列表框中一样选择

  • 复选框是内置的
  • 像在列表框中一样选择需要自定义树控件

CodeProject上提供了一个多选树控件:

我们曾经在WTL项目中这样做过一次,但所需的基本工作与.NET相同。要实现多选树控件,您需要自己绘制树项并覆盖键盘和鼠标处理。您还需要维护自己选择的项目列表


不要忘记考虑选择规则(例如父母和孩子允许),不要忘记使用快捷键,包括使用Ctrl、Shift和Ctrl + Shift来选择键盘快捷键,以及选择/取消选择的空格键。

< P>你可以查看第三方解决方案。树就是这样做的。不是免费的,但是花在寻找解决方案上的时间也不是真正免费的。

最简单的解决方案是扩展框架附带的现有TreeView控件,并用逻辑覆盖OnBeforeSelect和OnAfterSelect方法以捕获多个选择


此处可以找到一个示例:

下面的代码将允许您调整使用的背景颜色,以确保高亮显示所有选定的节点

protected override void WndProc(ref Message m)
{
    switch (m.Msg) {
        // WM_REFLECT is added because WM_NOTIFY is normally sent just
        // to the parent window, but Windows.Form will reflect it back
        // to us, MFC-style.
        case Win32.WM_REFLECT + Win32.WM_NOTIFY: {
            Win32.NMHDR nmhdr = (Win32.NMHDR)m.GetLParam(typeof(Win32.NMHDR));
            switch((int)nmhdr.code) {
                case Win32.NM_CUSTOMDRAW:
                    base.WndProc(ref m);
                    Win32.NMTVCUSTOMDRAW nmTvDraw = (Win32.NMTVCUSTOMDRAW)m.GetLParam(typeof(Win32.NMTVCUSTOMDRAW));
                    switch (nmTvDraw.nmcd.dwDrawStage) {
                        case Win32.CDDS_ITEMPREPAINT:
                            // Find the node being painted.
                            TreeNode n = TreeNode.FromHandle(this, nmTvDraw.nmcd.lItemlParam);
                            if (allSelected.Contains(n))
                                // Override its background colour.
                                nmTvDraw.clrTextBk = ColorTranslator.ToWin32(SystemColors.Highlight);
                            m.Result = (IntPtr)Win32.CDRF_DODEFAULT;  // Continue rest of painting as normal
                            break;
                    }
                    Marshal.StructureToPtr(nmTvDraw, m.LParam, false);  // copy changes back
                    return;
            }
            break;
        }
    }
    base.WndProc(ref m);
}

// WM_NOTIFY notification message header.
[System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
public class NMHDR
{
    private IntPtr hwndFrom;
    public IntPtr idFrom;
    public uint code;
}

[StructLayout(LayoutKind.Sequential)]
public struct NMCUSTOMDRAW
{
    public NMHDR hdr;
    public int dwDrawStage;
    public IntPtr hdc;
    public RECT rc;
    public IntPtr dwItemSpec;
    public int uItemState;
    public IntPtr lItemlParam;
}

[StructLayout(LayoutKind.Sequential)]
public struct NMTVCUSTOMDRAW
{
    public NMCUSTOMDRAW nmcd;
    public int clrText;
    public int clrTextBk;
    public int iLevel;
}

public const int CDIS_SELECTED = 0x0001;
public const int CDIS_FOCUS = 0x0010;
public const int CDDS_PREPAINT = 0x00000001;
public const int CDDS_POSTPAINT = 0x00000002;
public const int CDDS_PREERASE = 0x00000003;
public const int CDDS_POSTERASE = 0x00000004;
public const int CDDS_ITEM = 0x00010000;  // item specific 
public const int CDDS_ITEMPREPAINT = (CDDS_ITEM | CDDS_PREPAINT);
public const int CDDS_ITEMPOSTPAINT = (CDDS_ITEM | CDDS_POSTPAINT);
public const int CDDS_ITEMPREERASE = (CDDS_ITEM | CDDS_PREERASE);
public const int CDDS_ITEMPOSTERASE = (CDDS_ITEM | CDDS_POSTERASE);
public const int CDDS_SUBITEM = 0x00020000;
public const int CDRF_DODEFAULT = 0x00000000;
public const int CDRF_NOTIFYITEMDRAW = 0x00000020;
public const int CDRF_NOTIFYSUBITEMDRAW = 0x00000020;  // flags are the same, we can distinguish by context

public const int WM_USER = 0x0400;
public const int WM_NOTIFY = 0x4E;
public const int WM_REFLECT = WM_USER + 0x1C00;

这不是我真正想要的。Windows中的其他每个树视图都允许您按住ctrl键并单击“选择多个条目”。在“标准”Windows操作系统环境中,我找不到ctrl-click树视图的示例。你能举个例子吗?我同意checks中的上下文菜单不是很明智,但我认为期望用户按住ctrl键并单击也不是明智之举。(在我的实验中,很多用户都有这个问题。)对于标准Windows窗体树视图,这就是在树中选择多个节点的方式。好的,“standard”可能是错误的词。以VisualStudio中的解决方案资源管理器为例,问题是免费使用的“标准”控件(VS附带的控件)不一定是Windows中实际使用的控件。你有三个选择1)复选框2)写下你自己的3)买一个。糟透了,我知道。在WPF中很容易做到-1:我花了不到5分钟的时间找到一个简单的免费软件,并在我的解决方案中实现它。这里有两个样本:。不是完美的,但是如果你知道你的方法,它可以工作并且可以改进。@synhershko:文章分别是2004年和2002年的,我相信今天有更好的方法来实现同样的事情。尽管它是旧的(2004年),第一个实现是可靠的,并且编码良好。它适合于继承TreeView的一个类,并且非常易于调整。您可以通过截取WM_NOTIFY并调整选定节点的背景颜色来自行绘制。我添加了一个答案,这样我就可以包含代码了。@OliverBock:如果你只需要改变背景颜色,那当然是最简单的方法了。