アプリ版:「スタンプのみでお礼する」機能のリリースについて

VB.net(2010 Express)でTreeViewコントロールを使用し、子ノードと子ノードの間にドラックアンドドロップする際に線を表示したいのですが、どのようにすれば良いのか分かりません。
単純に子ノードのドラッグアンドドロップはできるのですが、子ノード同士の間に線を表示する方法が分からずにハマっています!!
添付しました画像の様な線を表示できる方法など分かる方がいましたら、お力をお貸しください。
宜しくお願い致します。

「VB.net TreeViewコントロー」の質問画像

A 回答 (3件)

  private void treeView1_MouseMove(object sender, MouseEventArgs e)


  {
    TreeNode clickedNode = treeView1.GetNodeAt(e.X, e.Y);
    if (e.Button == MouseButtons.Left && allowLine == false)
    {
      allowLine = true;
      if (this.VisibleDraggedNodeLabel == true)
      {
        motionLabel.Visible = true;
      }
      
    }
    if (allowLine == true)
    {

      //motionLabel.Location = Cursor.Position;
      Point client = treeView1.PointToClient(Cursor.Position);
      
      if (clickedNode != null && this.VisibleDraggedNodeLabel==true)
      {
        motionLabel.Location = new Point(treeView1.Bounds.X+clickedNode.Bounds.X+(clickedNode.Bounds.Width/2),
          treeView1.Bounds.Y+clickedNode.Bounds.Y+(clickedNode.Bounds.Height/2));
      }
      treeView1.Invalidate();

    }
  }
}

TreeViewクラス、TreeNodeクラス、TreeNode.DrawModeプロパティのヘルプを参考になさってください。
    • good
    • 0

(承前)


  private void treeView1_MouseDown(object sender, MouseEventArgs e)
  {
    treeView1.Capture = true;
    TreeNode clickedNode = treeView1.GetNodeAt(e.X, e.Y);
    if (clickedNode != null)
    {
      if (NodeBounds(clickedNode).Contains(e.X, e.Y))
      {
        treeView1.SelectedNode = clickedNode;
        if (this.VisibleDraggedNodeLabel == true) motionLabel.Text = clickedNode.Text;
      }
      
    }
  }

  private void treeView1_DrawNode(object sender, DrawTreeNodeEventArgs e)
  {
    drawcount++;
    this.Text = drawcount.ToString() + " " + e.State;
    // Draw the background and node text for a selected node.

    if ((e.State & TreeNodeStates.Selected) != 0)
    {
      e.Graphics.FillRectangle(Brushes.Green, NodeBounds(e.Node));

      Font nodeFont = e.Node.NodeFont;
      if (nodeFont == null) nodeFont = ((TreeView)sender).Font;

      // Draw the node text.
      e.Graphics.DrawString(e.Node.Text, nodeFont, Brushes.White,
      e.Node.Bounds.X + 2, e.Node.Bounds.Y);

      using (Pen focusPen = new Pen(Color.Black))
      {
        focusPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
        Rectangle focusBounds = NodeBounds(e.Node);
        focusBounds.Size = new Size(focusBounds.Width - 1,
        focusBounds.Height - 1);
        e.Graphics.DrawRectangle(focusPen, focusBounds);
      }
    }
    else
    {// Use the default background and node text.
      e.DrawDefault = true;
    }

    if (allowLine == true)
    {
      Graphics g = e.Graphics;
      Point client = treeView1.PointToClient(Cursor.Position);
      TreeNode clickedNode = treeView1.GetNodeAt(client);
      if (clickedNode != null)
      {

        int x = treeView1.Width;
        int y = clickedNode.Bounds.Y;

        //g.DrawArc(pen, -4, y - 4, 8, 8, 0, 360);
        g.FillPolygon(Brushes.Black, new Point[]{new Point(0+5,y-4),
                                 new Point(0+5,y+4),
                                 new Point(4+5,y)});
        g.DrawLine(pen, 3 + 5, y, x - 3 - 5, y);       //y = clickedNode.bound.y
        g.FillPolygon(Brushes.Black, new Point[]{new Point(x-5,y-4),
                                 new Point(x-5,y+4),  
                                 new Point(x-4-5,y)});
      }

    }

    // If a node tag is present, draw its string representation
    // to the right of the label text.
    if (e.Node.Tag != null)
    {
      e.Graphics.DrawString(e.Node.Tag.ToString(), tagFont,
        Brushes.Yellow, e.Bounds.Right + 2, e.Bounds.Top);
    }

    // If the node has focus, draw the focus rectangle large, making
    // it large enough to include the text of the node tag, if present.
    if (((e.State & TreeNodeStates.Focused) != 0) ||
      (e.State & TreeNodeStates.Selected) != 0)
    {
      using (Pen focusPen = new Pen(Color.Black))
      {
        focusPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
        Rectangle focusBounds = NodeBounds(e.Node);
        focusBounds.Size = new Size(focusBounds.Width - 1,
        focusBounds.Height - 1);
        e.Graphics.DrawRectangle(focusPen, focusBounds);
      }
    }
  }

  private Rectangle NodeBounds(TreeNode node)
  {
    // Set the return value to the normal node bounds.
    Rectangle bounds = node.Bounds;
    if (node.Tag != null)
    {
      // Retrieve a Graphics object from the TreeView handle
      // and use it to calculate the display width of the tag.
      Graphics g = treeView1.CreateGraphics();
      int tagWidth = (int)g.MeasureString
        (node.Tag.ToString(), tagFont).Width + 6;

      // Adjust the node bounds using the calculated value.
      bounds.Offset(tagWidth/2, 0);
      bounds = Rectangle.Inflate(bounds, tagWidth/2, 0);
      g.Dispose();
     }

    return bounds;

  }
    • good
    • 0

VB.netの環境がなく、C#で申し訳ありませんが…。



treeView1と、motionLabel(Label)を配置します。
treeView.DrawModeは、OwnerDrawTextとします。
VisibleDraggedNodeLabelがTrueの場合はドラッグ時にドラッグをしているノード名がmotionLabelに表示されます。不要ならばfalse。

TreeViewの描画はDrawNode内部で。コンポーネントの操作や再描画契機(Invalidate)の発行はMouseXXXイベントで行なっています。

この事例では、ノード間のドラッグアンドドロップに対応しており、アイコンなどを外側からドラッグしてくる状況を考える場合にはイベントなどを考慮する必要があります。

public partial class Form1 : Form
{
  int drawcount = 0;
  private bool allowLine = false;
  Pen pen;
  //Graphics g = null;
  Font tagFont = new Font("Helvetica", 8, FontStyle.Bold);

  private bool _visibleMotionLabel = true;
  public bool VisibleDraggedNodeLabel{
    get
    {
      return _visibleMotionLabel;
    }
    set
    {
      _visibleMotionLabel = value;
    }
  }
  private void Form1_Load(object sender, EventArgs e)
  {
    allowLine = false;
    motionLabel.Location = new Point(-100, 10);
    motionLabel.BackColor = Color.Transparent;
    this.VisibleDraggedNodeLabel = true;
    pen = new Pen(Color.Black, 2);
  }

  private void treeView1_MouseLeave(object sender, EventArgs e)
  {
    treeView1.Capture = false;
  }

  private void treeView1_MouseUp(object sender, MouseEventArgs e)
  {
    treeView1.Capture = false;
    if (allowLine == true)
    {
      motionLabel.Location = new Point(-100, 10);
      motionLabel.Visible = false;
      allowLine = false;

    }
    treeView1.Invalidate();
  }
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!