2011-09-14 22 views
1

我有一個簡單的TreeView,其HotTracking屬性設置爲True。當我將鼠標移動到一個項目上時,它可以工作。但是,當我使用Drag &拖放並拖動TreeView項目時,它不起作用。有沒有辦法使用DragDrop的HotTracking?或者任何解決方法?TreeView中的HotTracking無法使用Drag&Drop

回答

1

按設計,控件只獲取D + D通知,沒有鼠標消息。您可以簡單地選擇節點:

private void treeView1_DragOver(object sender, DragEventArgs e) { 
     if (e.Data.GetDataPresent("something")) { 
      var pos = treeView1.PointToClient(new Point(e.X, e.Y)); 
      var hit = treeView1.HitTest(pos); 
      if (hit.Location == TreeViewHitTestLocations.Label) { 
       treeView1.SelectedNode = hit.Node; 
       e.Effect = DragDropEffects.Copy; 
      } 
      else e.Effect = DragDropEffects.None; 
     } 
    } 

您通常需要做更多工作才能讓用戶滾動視圖並展開節點。

+0

選擇節點是不一樣的hotTracking。有沒有辦法告訴樹畫節點,好像它是熱點?沒有自繪邊框,標識,圖標和文字更好。我遇到了與TreeView相同的問題(由SetWindowTheme(「explorer」)擴展)。 – DimDim

0

選擇節點爲@Hans建議的是一個簡單的解決方案,但如果節點選擇中存在某些事件,或者您只需要保留選定節點,則該解決方案可能無法使用。 我發現的唯一方法是使用VisualStylesRenderer的custumDraw節點。

private void plTree_DragOver(object sender, DragEventArgs e) 
    {    
     Point pt = plTree.PointToClient(new Point(e.X, e.Y)); 

     var overNode = plTree.GetNodeAt(pt); 
     bool canMoveTo = overNode != null && 
         TreeNodeIsFolder(overNode) && 
         !IsFirstNodeParentToSecond(GetDraggedNodes(e)[0], overNode);// all dragged nodes are of the same parent 
     e.Effect = canMoveTo ? DragDropEffects.Move : DragDropEffects.None; 

     if (overNode == null) return; 

     if (_lastCustomDrawNode != overNode) 
     { 
      NormalDrawNode(_lastCustomDrawNode); 
      CustomDrawNode(overNode); 
     } 
     _lastCustomDrawNode = overNode; 
    } 

    private void NormalDrawNode(TreeNode aNode) 
    { 
     if (aNode == null) return; 

     if (_normalNodeRenderer == null) 
      _normalNodeRenderer = new VisualStyleRenderer("Explorer::TreeView", 1, 1); 
     Debug.WriteLine("normal render" + DateTime.Now); 
     RenderTreeNode(_normalNodeRenderer, aNode, true); 

     _lastCustomDrawNode = null; 
    } 

    private void CustomDrawNode(TreeNode aNode) 
    { 
     if (_hotNodeRenderer == null) 
      _hotNodeRenderer = new VisualStyleRenderer("Explorer::TreeView", 1, 2); 
     Debug.WriteLine("custom render" + DateTime.Now); 
     RenderTreeNode(_hotNodeRenderer, aNode, false); 
    } 

    private void RenderTreeNode(VisualStyleRenderer renderer, TreeNode aNode, bool drawDefaultBck) 
    { 
     if(_treeGraphics == null) 
      _treeGraphics = plTree.CreateGraphics(); 

     const int iconShift = 21; 
     Rectangle aRec = aNode.Bounds; 

     var bckRec = new Rectangle(aRec.Location.X - iconShift, aRec.Location.Y, aRec.Width + iconShift, aRec.Height); 

     if (!drawDefaultBck) 
      renderer.DrawBackground(_treeGraphics, bckRec); 
     else 
      _treeGraphics.FillRectangle(_treebckgBrush, bckRec); 

     var textRec = new Rectangle(aRec.Location.X + 1, aRec.Location.Y - 1, aRec.Width, aRec.Height); 
     TextRenderer.DrawText(_treeGraphics, aNode.Text, GetTreeNodeFont(aNode), textRec, Color.FromKnownColor(KnownColor.ControlText)); 

     var imgRec = new Rectangle(aRec.Location.X + 2 - iconShift, aRec.Location.Y, 16, 16); 
     renderer.DrawImage(_treeGraphics, imgRec, ImageListTree.Images[aNode.ImageIndex]); 
    } 

這個帖子有很大幫助與主題圖中: VisualStyleRenderer and themes (WinForms)

+0

順便說一句有人可以告訴我如何動態獲取「IconShift」,而不是硬編碼? – DimDim