2011-01-28 90 views
19

欲除去的CheckBox其中Node.Type是5或6。我使用此代碼刪除複選框不在那裏。 如何刪除複選框並讓圖像和線條出現?樹視圖由一些節點

This is wrong!

+0

可能重複](http://stackoverflow.com/questions/4179522/i-am-looking-for-a-good-resource-on-ownerdrawn-treeviews) – 2011-01-28 09:44:57

+0

我同意漢斯;業主抽籤通常非常困難。如果你堅持,我發現了一個更完整的自繪樹視圖樣本,作爲[這個問題]的答案給出(http://stackoverflow.com/questions/1003459/c-treeview-owner-drawing-with-ownerdrawtext-和怪異的黑色突出顯示wh/1004087),完成與節點線。 – 2011-01-28 09:54:34

回答

63

在你所示的代碼,你正在處理的圖紙自己所有的類型爲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 structureSendMessage function。底部是您實際打電話的功能(HideCheckBox)。您只需傳入TreeView控件和要從中刪除複選標記的特定TreeNode項目。

所以,你可以從每個子節點取消複選標記得到的東西,看起來像這樣:

      TreeView with checkmarks hidden for child nodes

4

這是非常好的!我所做的唯一修改是隻通過TreeNode而不是TreeViewHideCheckBox方法。該TreeView可以從TreeNode本身檢索:

TreeView tvw = node.TreeView; 
13

使用TreeViewExtensions。

用法示例:

private void MyForm_Load(object sender, EventArgs e) 
{ 
    this.treeview1.DrawMode = TreeViewDrawMode.OwnerDrawText; 
    this.treeview1.DrawNode += new DrawTreeNodeEventHandler(arbolDependencias_DrawNode); 
} 

void treeview1_DrawNode(object sender, DrawTreeNodeEventArgs e) 
{ 
    if (e.Node.Level == 1) e.Node.HideCheckBox(); 
    e.DrawDefault = true; 
} 

下面是答案的代碼作爲擴展方法,用這個你可以這樣做:

public static class TreeViewExtensions 
{ 
    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> 
    public static void HideCheckBox(this TreeNode node) 
    { 
     TVITEM tvi = new TVITEM(); 
     tvi.hItem = node.Handle; 
     tvi.mask = TVIF_STATE; 
     tvi.stateMask = TVIS_STATEIMAGEMASK; 
     tvi.state = 0; 
     SendMessage(node.TreeView.Handle, TVM_SETITEM, IntPtr.Zero, ref tvi); 
    } 
} 
的[我要尋找的ownerdrawn樹視圖一個很好的資源