2009-03-30 4 views
17

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

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

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

Есть ли у кого-нибудь простые и надежные решения?

ответ

32

Поскольку в 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; 

    } 

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

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); 
} 
+3

В функции HideCheckBox измените tvi.state = 0 на tvi.state = 1 << 12. В MSDN предоставляется объяснение statemasks: http://msdn.microsoft.com/en- us/library/bb760017 (VS.85) .aspx –

+1

Когда я пытаюсь это сделать, галочка заканчивается тем, что обрезается на узле, на котором есть флажок. –

+0

Используете ли вы свойства отображения по умолчанию для TreeView? Если вы используете свой собственный флажок, он может быть слишком большим ... вы можете исправить это, нарисуя текст узла самостоятельно, слегка сдвинув его вправо. –

0

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

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

+0

Это на первый взгляд простое и чистое решение. Единственная проблема с этим - если пользователь дважды щелкает этот флажок, он все равно переходит в состояние проверки. Поэтому, если он захочет использовать этот метод, ему придется выполнить дополнительную проверку, чтобы это не произошло. :) – Abbas

0

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

Возможно, это вас интересует link.

Смежные вопросы