【问题标题】:Dragging in steps逐步拖动
【发布时间】:2013-12-10 18:54:07
【问题描述】:

我有一个分成 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;
        }
    }
}

【问题讨论】:

    标签: c# winforms mouseevent drag


    【解决方案1】:

    在 'OnDrag' 事件中,您需要检查当前 Y 坐标是否在您的范围内,然后仅当值在所需范围内时才对 Top 值执行更新。

    在 StopDrag 事件中,您需要计算该排名中的项目的正确位置,并将对象的“顶部”值设置为所需的值以使其“捕捉”到正确的位置。

    我可以看到的问题是处理拖放的事件在您的 Marker 类中并且不知道全局环境,因此阻止您编写诸如'if (this.Y upperY) 然后什么也不做。对此有许多解决方案:将拖动事件处理程序移动到父容器上,以便它们知道所需的数据,使父容器具有某种形式的全局可见属性,这些属性在标记之一的范围内是可见的,或者可能为每个标记添加一个属性,使它们能够了解其父“容器”。

    【讨论】:

    • 感谢您的回复...请您用一些代码说明您的示例,因为我发现这个概念很难理解。
    猜你喜欢
    • 1970-01-01
    • 2018-12-15
    • 1970-01-01
    • 1970-01-01
    • 2010-09-08
    • 2021-04-01
    • 2012-10-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多