2013-12-10 61 views
0

我有一個面板被分成10個相等的行。然後我有標記(高度爲一行的高度的正方形),我希望能夠上下拖動,但標記需要完全適合一行。一個標記不能被拖拽到第1行一半,第2行另一半的位置。因此拖動必須處於特定的垂直位置。 我只需要垂直拖動。然後,我需要分配行標記已被移動到對象的屬性。例如。如果標記放置在第5行,那麼該對象的排名將被分配到5. 這是我迄今爲止所做的,我可以垂直拖動每個標記,問題是它們可以在外面父容器,並且我不能讓它們只移動到所需的y位置。 任何想法或解釋我如何實現這一目標...請隨時詢問我的問題是否不太清楚..謝謝。在步驟中拖動

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Drawing; 

namespace MouseDragTest 
{ 
    class Marker : PictureBox 
    { 
     public Label lb1 = new Label(); 
     public Label lb2 = new Label(); 
     bool isDragging = false; 
     int rank; 

     //-------Constructor---------- 
     public Marker(int xLoc, int yLoc) 
     { 
      Location = new Point(xLoc, yLoc); 
      this.Size = new Size(20, 20); 
      this.BackColor = Color.Blue; 
      this.BringToFront(); 

     //-------Mouse Event Handlers-------- 
      this.MouseDown += new MouseEventHandler(StartDrag); 
      this.MouseUp += new MouseEventHandler(StopDrag); 
      this.MouseMove += new MouseEventHandler(OnDrag); 
     } 

     //-------Mouse Event Handlers Implementation--------- 
     private void StartDrag(object sender, MouseEventArgs e) 
     { 
      if (e.Button == MouseButtons.Left) 
      { 
       isDragging = true; 
       rank = (this.Top + e.Y); 
      } 
     } 

     private void StopDrag(object sender, MouseEventArgs e) 
     { 
      if (e.Button == MouseButtons.Left) 
      { 
       isDragging = false; 
       rank = this.Top + e.Y;     
       lb1.Text = rank.ToString(); //Info on blue square 
       lb2.Text = rank.ToString(); //Info on red square 
      } 
     } 

     private void OnDrag(object sender, MouseEventArgs e) 
     { 
      if (isDragging) 
      { 
       this.Top = this.Top + e.Y; //move vertically; 
      } 
     } 

     protected override void OnPaint(PaintEventArgs pe) 
     { 
      base.OnPaint(pe); 
     } 
    } 
    } 

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 

namespace MouseDragTest 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void panel1_Paint(object sender, PaintEventArgs e) 
     { 
      Graphics g = e.Graphics; 
      Pen p = new Pen(Color.Black, 1); 

      int yLoc = 20; 
      for (int i = 0; i < 10; i++) 
      { 
       g.DrawLine(p, 0, yLoc, this.Width, yLoc);yLoc += 20; 
      } 

     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      Marker mk1 = new Marker(0, 0); 
      panel1.Controls.Add(mk1); 
      /*For testing*/ mk1.lb1 = label1; 

      Marker mk2 = new Marker(20,0); 
      panel1.Controls.Add(mk2); 
      /*For testing*/ mk2.lb2 = label2; 
      mk2.BackColor = Color.Red; 
     } 
    } 
} 

回答

1

在「ondrag當」事件中,你需要檢查當前Y座標是你的範圍內,然後再執行更新僅如果值是在所需範圍內的頂值。

在StopDrag事件中,您需要計算此排名中某個項目的正確位置,並將該對象的'Top'值設置爲所需值以使其'正確'到正確的位置。

我可以看到的問題是,處理拖放操作的事件在Marker類中,並且不知道全局環境,從而導致您無法編寫代碼,如'if(this.Y < lowerY || this.Y> upperY)然後什麼都不做。有許多解決方案:將拖動事件處理程序移動到父容器上,以便它們知道所需的數據,使父容器具有某種形式的全局可見屬性,這些屬性在其中一個標記的範圍內可見,或者可能爲每個標記添加一個屬性,以使他們知道他們的父容器。

+0

感謝您的回覆...請你可以用一些代碼說明你的例子,因爲我發現這個概念很難理解。 – user2307236

+0

任何線索或例子我如何解決這個問題?任何幫助是極大的讚賞... – user2307236