我有一个分为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;
}
}
}
答案 0 :(得分:1)
在'OnDrag'事件中,您需要检查当前Y坐标是否在您的范围内,然后仅在值处于所需范围内时才对Top值执行更新。
在StopDrag事件中,您需要为此等级中的项目计算正确的位置,并将对象的“顶部”值设置为所需的值,以使其“捕捉”到正确的位置。
我可以看到的问题是,处理拖放操作的事件位于Marker类中,并且不知道全局环境,从而阻止您编写代码,例如'if(this.Y&lt; lowerY) || this.Y&gt; upperY)然后什么都不做。有许多解决方案:将拖动事件处理程序移动到父容器上,以便它们知道所需的数据,使父容器具有某种形式的全局可见属性,这些属性在其中一个标记的范围内可见,或者可能为每个标记添加一个属性,使它们能够知道它们的父“容器”。