首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

有关于MouseDown事件里如何去监听MouseDown有没有被触发

2011-12-28 
有关于MouseDown事件里怎么去监听MouseDown有没有被触发Form上有一个圆点,当我鼠标在Form上点了一点之后,

有关于MouseDown事件里怎么去监听MouseDown有没有被触发
Form上有一个圆点,当我鼠标在Form上点了一点之后,圆点就向我的鼠标点移动,如果这个时候我再点一下,我希望鼠标按照我新点的位置移动,就是说我必须在MouseDown事件里去监听MouseDown是不是再次被触发

请各位高手教教小弟!

[解决办法]
你在MouseDown事件里面写上相应的操作代码不就行了 还要监听什么?直接有这个事件
[解决办法]
在窗体上加入成员标志
bool IsFirstDown = false;
在MouseDown中判断
if(!IsFirstDown)
IsFirstDown = true; // 当前是第一次按下
else
IsFirstDown = false;
[解决办法]
圆点是控件?还是GDI画图?

-----------------
如果圆点是控件(如imageBox),只要分别监听Form和控件的MouseDown

如果是GDI画图,只要在Form类里加一个bool标识变量!
[解决办法]
你在MouseDown事件里面写上相应的操作代码不就行了 还要监听什么?直接有这个事件

同意这种意见,直接MouseDown事件里面写就行了
MouseDown事件里的代码的任务就是把圆点移动到鼠标所在处

[解决办法]
压根就不存在需要监听的问题~~~~


不过如果你一定要监听,有的是方法,Windows消息也行, 用事件委托也行
[解决办法]
lz说的应该是圆点移动的动画效果吧,圆点向鼠标点击位置移动有个过程,比如说在1秒钟内平均速度移动过去。在0.5秒的时候鼠标又在另外一个位置点击了一下,然后要让圆点移动方向改变成朝新的点击位置移动,对不对?

保存2个位置,一个圆点当前位置,一个是鼠标点击位置。每次鼠标点击时记录鼠标点击位置。每隔一段时间(比如说0.1秒)将圆点位置向保存的鼠标点击位置移动一定距离。
[解决办法]
至少需要保存2个变量,就是圆点当前位置和鼠标点击位置。如果你不想用定时器每隔一段时间重绘圆点位置的话,循环不能用局部变量判断,要放在Form里作为成员变量。

比如
Form{
Point start;
Point target;
Point current;
int step;
bool isMoving = false;

void MouseClick(MouseEventArgs e){
start = current;
target = e.Point;
step = 0;
if(!isMoving){
isMoving = true;
for(;step < max;step++){
current = GetCurrent(start ,target ,step);
Draw();
sleep(100);//这里用sleep应该不行,换成你自己所实现的定时
}
isMoving = false;
}
}

自己看下可不可以改,最好要加上同步。
[解决办法]
想法:
圆点移动需要另外启动一个线程
这个线程和界面的UI线程进行交互
交互的数据就是你点击位置
新线程每移动一步
都根据UI线程中通过MouseClick事件的得到的新的位置进行方向调整
然后在移动,直到与点击位置重合
[解决办法]
你是怎么绘图的,用自己写的线程还是用Timer控件定时控制?
我想你不会是用简单的for循环来控制吧??

无论是线程还是Timer,过程应该是
1.MouseDown事件接收到鼠标的点击事件;
2.判断绘图线程是否启动(即判断绘图标志是否启动 if(!drawing) ),如果没有启动,那么开始启动绘图线程,设置绘图标志为正在绘制的状态 drawing = true,同时在全局变量(可以设置为静态)中记录目标的位置X和Y; 如果已经启动,那么重新设置X,Y的值,线程应该会根据X,Y的值重新计算移动的方向并移动.
3.移动到目标点,设置drawing = false,等待下一次的命令

[解决办法]
中途有点了自动就会停止当前动作处理新的移动事件了
要全局变量判断第几次干什么?
[解决办法]
设置个标志嘛
比如弄个GUID表示最后次鼠标点击生成的标志,循环移动的时候判断这个标志

窗体类里面申明一个
private string id;

mousedown:
id = Guid.NewGuid().ToString();

move:
string oldid = id;
while(oldid == id)
{
.......
}
[解决办法]
你代码怎么写的 最好贴一下
如果x y存在全局里面还是不需要bool变量的
[解决办法]
你是直接用Form的sleep()吗?那样不行,线程停了就不会响应click事件了。
要另外起个线程,用VS提供的定时器好了。
[解决办法]
aaajedll() :


current = GetCurrent(start ,target ,step);
Draw();
这里是每次移动的时候都是根据起始点和终点以及移动几次重新计算当前的坐标,然后Draw()就是在当前坐标画出圆点。如果在移动过程中start ,target ,step改变了,求出的坐标也随之改变。
[解决办法]
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace MovePoint
{
public partial class Form1 : Form
{


#region Designer
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;

/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name= "disposing "> true if managed resources should be disposed; otherwise, false. </param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}

#region Windows Form Designer generated code

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.timer1 = new System.Windows.Forms.Timer(this.components);
this.SuspendLayout();
//
// timer1
//
this.timer1.Interval = 10;
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(483, 419);
this.Name = "Form1 ";
this.Text = "Form1 ";
this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);
this.MouseClick += new System.Windows.Forms.MouseEventHandler(this.Form1_MouseClick);
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);

}

#endregion

private System.Windows.Forms.Timer timer1;

#endregion

private int endPointx = 0;
private int endPointy = 0;
private int currentPointx = 0;
private int currentPointy = 0;
private int startPointx = 0;
private int startPointy = 0;
private int stepx = 0;
private int stepy = 0;
private double sida = 0;//斜率

public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
this.timer1.Start();
}

private void timer1_Tick(object sender, EventArgs e)
{
this.Refresh();
}

private void Form1_Paint(object sender, PaintEventArgs e)
{
Pen pen = new Pen(Color.Red);
Graphics panit = e.Graphics;
panit.DrawEllipse(pen, currentPointx, currentPointy, 2, 2);



if (currentPointx == endPointx && currentPointy == endPointy)
return;

//防止斜率无穷大
if (currentPointx == endPointx)
{
currentPointy += stepy;
return;
}

int liney = (int)(sida*(currentPointx - startPointx) + startPointy);

//判断是前进x还是前进y
if ((liney - currentPointy) * stepy > 0)
{
currentPointy += stepy;
}
else
{
currentPointx += stepx;
}
}

private void Form1_MouseClick(object sender, MouseEventArgs e)
{
endPointx = e.X;
endPointy = e.Y;
startPointx = currentPointx;
startPointy = currentPointy;

if (endPointx == currentPointx)
stepx = 0;
if (endPointx > currentPointx)
stepx = 1;
if (endPointx < currentPointx)
stepx = -1;

if (endPointy == currentPointy)
stepy = 0;
if (endPointy > currentPointy)
stepy = 1;
if (endPointy < currentPointy)
stepy = -1;

//防止斜率无穷大
if (endPointx == startPointx)
return;

sida = (double)(endPointy - startPointy)
/ (double)(endPointx - startPointx);
}
}
}


我写例子,作为参考吧:)
[解决办法]
其中移动点的算法是仿照数控加工中板材切割的算法:)
想了好长的时间-_- " "

如果把事件做成mouse_move更有意思....
[解决办法]
换个思路
1。定义一个队列,存放圆圈移动的路径
2。在MouseDown事件里重新计算当前圆圈位置和鼠标位置之间的路径,刷新移动路径队列
3。定时器,定时从路径队列中取出一个位置画圆
[解决办法]
改良一下

换个思路
1。定义一个队列,存放圆圈移动的路径
2。定义一个当前圆的位置变量 Point m_CurrentPoint
2。在MouseDown事件里重新计算m_CurrentPoint和鼠标位置之间的路径,刷新移动路径队列
3。定时器,定时从路径队列中取出一个位置付给m_CurrentPoint,并刷新Form
4。在Form的Paint方法里在m_CurrentPoint处画圆


[解决办法]
手有电脑反应快?

[解决办法]
学习一个
[解决办法]
现在的问题是怎么去获得鼠标再次被点击???

我觉得不用判断鼠标什么时候点击的.
每次点击的时候是对一个全局变量进行更新
private void Form1_MouseClick(object sender, MouseEventArgs e)
{
endPointx = e.X;
endPointy = e.Y;
startPointx = currentPointx;
startPointy = currentPointy;

if (endPointx == currentPointx)
stepx = 0;
if (endPointx > currentPointx)
stepx = 1;
if (endPointx < currentPointx)
stepx = -1;

if (endPointy == currentPointy)
stepy = 0;
if (endPointy > currentPointy)
stepy = 1;
if (endPointy < currentPointy)
stepy = -1;

//防止斜率无穷大
if (endPointx == startPointx)
return;

sida = (double)(endPointy - startPointy)


/ (double)(endPointx - startPointx);
}

我们通过timer每次刷新都是根据最新的点击位置计算就可以了.
[解决办法]
我的代码拷贝粘贴,可以直接运行的
[解决办法]
晕啊,楼主,你的代码是在MouseDown中直接用for循环+Thread.Sleep()进行绘图,在这种情况下UI怎么可能接收消息队列里面的其他信息,你第二次的鼠标点击在移动绘图完成之前都不会被处理,所以移动方向自然不会改变了.
你要换成用子线程或者timer进行绘图才有可能与主界面进行互动啊,要不你就在for循环中增加
Application.DoEvent()让系统处理一下消息队列里面的其他信息.不过按照你现在的设计结构,用Application.DoEvent()是解决不了问题的.
[解决办法]
用Timer比较好,用另外的线程的话还要解决界面刷新的问题,比较麻烦。

public class Form1 : Form
{
private Timer;
private const int MaxStep = 50;

private Point start;
private Point current;
private Point target;
private bool isMoving = false;
private int step = 0;

public Form1()
{
InitializeComponent();
timer1 = new Timer(this.components);
timer1.Interval = 50;
timer1.Tick += new EventHandler(this.timer1_Tick);
}

private void Form1_MouseClick(object sender, MouseEventArgs e)
{
start = current;
target = e.Location;
step = 0;
if (!isMoving)
{
isMoving = true;
timer1.Start();
}
}

private void timer1_Tick(object sender, EventArgs e)
{
if (step < MaxStep)
{
if (IsDisposed) return;
current.X = start.X + (target.X - start.X) * (step + 1) / MaxStep;
current.Y = start.Y + (target.Y - start.Y) * (step + 1) / MaxStep;
Refresh();
step++;
}
else
{
isMoving = false;
timer1.Stop();
}
}

private void Form1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.FillEllipse(Brushes.Black, new Rectangle(current, new Size(8, 8)));
}
}
[解决办法]
private Timer; 改成
private Timer timer1;
[解决办法]
To:danjiewu(阿丹)

觉得你算法很好哦!简单,好理解:)

不过我想:如果两个点很近那么也需要走50步
如果很远那么就跳跃性的走了
所以觉得你可以在click中设置一下maxstep
取处x方向和y方向上的比较长距离作为你的maxstep会显示比较好

[解决办法]
看你要实现什么样的移动效果了。
我这个是不管距离远近,移动时间是一样的。如果你要实现固定速度的移动或者加速减速的移动,在计算current的时候需要改一下,自己决定吧。


[解决办法]
提一点我的看法:

用一个变量来存储你当前圆点的位置,另一个变量存储最近一次鼠标点过的位置。再设一个Timer。在Timer中不断比较两个变量。如果不一样就让圆点的位置向最近一次鼠标点过的位置移动。

我想这样应该能实现楼主要的。只是效率可能不行,不过有兴趣还可以改善。
[解决办法]
smartstar2005()

想法是对的,效率并不低,定时对一个简单的int或者point变量的访问代价很小。
事实上,这个设计更好一些,简单而健壮。

热点排行