Ответ 1
В коде, который вы указали, вы сами обрабатываете чертеж для всех узлов с типом 5 или 6. Для остальных типов вы просто позволяете системе рисовать узлы в по умолчанию. Вот почему у всех есть линии, как ожидалось, но те, которые вы рисуете владельцем, не делают: вы забыли рисовать линии! Видите ли, когда вы говорите e.DrawDefault = false;
, это предполагает, что вы действительно это имеете в виду. Ни один обычный рисунок не выполняется, включая стандартные строки.
Вам нужно либо нарисовать эти строки самостоятельно, либо выяснить, как обойтись без рисования владельца.
Из кода, который у вас есть сейчас, похоже, что вы пытаетесь имитировать собственный стиль рисования системы в максимально возможной степени в коде вашего владельца-рисования, поэтому мне не ясно, что именно вы выполняете с помощью рисования владельца первое место. Если вы просто пытаетесь сохранить флажки для узлов типа 5 и 6 (которые, как и строки, просто не рисуются, потому что вы их не рисуете!), Есть более простой способ сделать это без привлечения владельца рисунок.
Итак, вы спрашиваете, что это более простой способ скрыть флажки для отдельных узлов? Ну, оказывается, что сам контроль TreeView
фактически поддерживает это, но эта функциональность не раскрывается в .NET Framework. Вам нужно P/Invoke и вызвать Windows API, чтобы получить от него. Добавьте следующий код в класс формы (убедитесь, что вы добавили объявление using
для System.Runtime.InteropServices
):
private const int TVIF_STATE = 0x8;
private const int TVIS_STATEIMAGEMASK = 0xF000;
private const int TV_FIRST = 0x1100;
private const int TVM_SETITEM = TV_FIRST + 63;
[StructLayout(LayoutKind.Sequential, Pack = 8, CharSet = CharSet.Auto)]
private 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;
}
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam,
ref TVITEM lParam);
/// <summary>
/// Hides the checkbox for the specified node on a TreeView control.
/// </summary>
private void HideCheckBox(TreeView tvw, TreeNode node)
{
TVITEM tvi = new TVITEM();
tvi.hItem = node.Handle;
tvi.mask = TVIF_STATE;
tvi.stateMask = TVIS_STATEIMAGEMASK;
tvi.state = 0;
SendMessage(tvw.Handle, TVM_SETITEM, IntPtr.Zero, ref tvi);
}
Все беспорядочные вещи вверху - это ваши объявления P/Invoke. Вам нужно несколько констант, структура TVITEM
, которая описывает атрибуты элемента treeview, и SendMessage
. В нижней части находится функция, которую вы на самом деле вызываете для совершения действия (HideCheckBox
). Вы просто передаете элемент управления TreeView
и конкретный элемент TreeNode
, из которого вы хотите удалить галочку.
Итак, вы можете удалить галочки с каждого из дочерних узлов, чтобы получить что-то похожее на это: