Как отключить флажок узла WinForms TreeView? - PullRequest
18 голосов
/ 30 марта 2009

Мне нужно иметь возможность отключить некоторые флажки в элементе управления TreeView приложения WinForms, но в стандартный элемент управления TreeView такой функциональности нет.

Я уже использую событие TreeView.BeforeCheck и отменяю его, если узел отключен, и это прекрасно работает.

Я также изменяю ForeColor отключенных узлов на GrayText.

У кого-нибудь есть простое и надежное решение?

Ответы [ 3 ]

33 голосов
/ 14 апреля 2009

Поскольку в C ++ есть поддержка, мы можем решить ее с помощью p / invoke.

Вот настройка для части p / invoke, просто сделайте ее доступной для вызывающего класса.

    // constants used to hide a checkbox
    public const int TVIF_STATE = 0x8;
    public const int TVIS_STATEIMAGEMASK = 0xF000;
    public const int TV_FIRST = 0x1100;
    public const int TVM_SETITEM = TV_FIRST + 63;

    [DllImport("user32.dll")]
    static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam,
    IntPtr lParam); 

    // struct used to set node properties
    public struct TVITEM
    {
        public int mask;
        public IntPtr hItem;
        public int state;
        public int stateMask;
        [MarshalAs(UnmanagedType.LPTStr)]
        public String lpszText;
        public int cchTextMax;
        public int iImage;
        public int iSelectedImage;
        public int cChildren;
        public IntPtr lParam;

    } 

Мы хотим определить для каждого узла. Самый простой способ сделать это - событие события отрисовки. Мы должны установить наше дерево в качестве владельца, нарисованного для этого события, поэтому обязательно установите для него значение, отличное от значения по умолчанию.

this.tree.DrawMode = TreeViewDrawMode.OwnerDrawText;
this.tree.DrawNode += new DrawTreeNodeEventHandler(tree_DrawNode);

В вашей функции tree_DrawNode определите, должен ли отображаемый узел иметь флажок, и скройте его при оценке. Затем установите для свойства Default Draw значение true, поскольку нам не нужно беспокоиться о рисовании всех остальных деталей.

void tree_DrawNode(object sender, DrawTreeNodeEventArgs e)
{
    if (e.Node.Level == 1)
    {
        HideCheckBox(e.Node);
        e.DrawDefault = true;
    }
    else 
    {
        e.Graphics.DrawString(e.Node.Text, e.Node.TreeView.Font,
           Brushes.Black, e.Node.Bounds.X, e.Node.Bounds.Y);
    }
}

Наконец, фактический вызов функции, которую мы определили:

private void HideCheckBox(TreeNode node)
{
    TVITEM tvi = new TVITEM();
    tvi.hItem = node.Handle;
    tvi.mask = TVIF_STATE;
    tvi.stateMask = TVIS_STATEIMAGEMASK;
    tvi.state = 0;
    IntPtr lparam = Marshal.AllocHGlobal(Marshal.SizeOf(tvi));
    Marshal.StructureToPtr(tvi, lparam, false);
    SendMessage(node.TreeView.Handle, TVM_SETITEM, IntPtr.Zero, lparam);
}
0 голосов
/ 30 марта 2009

Нет ничего встроенного, чтобы сделать это. Вы можете использовать событие BeforeCheck и отменить его для нужных узлов. В случае, если внешний вид флажка имеет значение, вам нужно будет поместить изображение там, чтобы показать, что флажок отключен.

Эта ссылка может вас заинтересовать.

0 голосов
/ 30 марта 2009

TreeView.BeforeCheck - зарегистрируйтесь для этого события, проверьте, является ли узел узлом, где флажки разрешены для проверки или нет, и, если это невозможно, вы можете отменить событие, задав свойство Cancel в TreeViewCancelEventArgs , Надеемся, что это должно помешать пользователю установить эти флажки, но не приведет к лучшему восприятию пользователем.

Чтобы снять флажки для не подлежащих проверке элементов, вы можете использовать владелец-рисование, чтобы нарисовать сплошной прямоугольник над флажком, чтобы удалить его.

...