我一直在试图创建一个自定义事件来处理鼠标控件等等,但我一直遇到某些错误,这些错误似乎都没有解决。我很确定我的创作/分配逻辑是正确的,但也许是我在这里遗漏的根本错误。
首先,我使用与方法相同的签名创建我的委托;
public delegate void MouseDown(object sender, MouseEventArgs e, Control control);
然后我将它分配给我的活动;
public event MouseDown OnMouseDown;
然后最后我尝试订阅该活动;
public static void Init(Control control, Control container, Direction direction)
{
control.MouseDown += OnMouseDown;
}
//ignore the parameters I'm passing, these are out of the scope of my problem.
然而,在本节中,我收到错误“非静态字段,方法或属性需要一个参考值”blah blah.OnMouseDown“”
最后继承我的方法我试图在mouseDown上订阅;
public void MouseDownEvent(object sender, MouseEventArgs e, Control control)
{
Dragging = true;
DragStart = new Point(e.X, e.Y);
control.Capture = true;
}
我试图修改我在某处找到的帮助程序类可能没有帮助。如果需要任何进一步的信息,请随时询问。
注意:此类的主要目标是允许在运行时移动控件。
修改
我相信前两个有效,但要移动我需要使用以下方法;
public void MouseMoveEvent(object sender, MouseEventArgs e, Control control, Control container, Direction direction)
{
if (Dragging)
{
if (direction != Direction.Vertical)
container.Left = Math.Max(0, e.X + container.Left - DragStart.X);
if (direction != Direction.Horizontal)
container.Top = Math.Max(0, e.Y + container.Top - DragStart.Y);
}
}
所以我需要发送方向指示,我无法作为发送方发送。我正在对整个系统进行这些更改的原因是,我在使用匿名委托之前已经工作了,但是当我想重新锁定控件时,这些很难取消订阅。
编辑2:
如果我没有传递正确的控件,那么mouseDown和mouseUp将不起作用,至少订阅我以前做过的方式。我可以尝试你的方法,但是,我这样做的方式我只是调用一个订阅所有3个MouseControls的方法。它看起来像我可以在sepearate方法中订阅建议,或者我需要正确地传递正确的控制,即不是发送者作为控制。任何想法?
目前我正在通过从任何地方运行此方法进行订阅;
helper.Init(this.Controls["btn" + i]);
然后在将按钮订阅到我的鼠标按钮之前运行这些方法,然后向下移动。
public static void Init(Control control)
{
Init(control, Direction.Any);
}
public static void Init(Control control, Direction direction)
{
Init(control, control, direction);
}
public static void Init(Control control, Control container, Direction direction)
{
control.MouseDown += new MouseEventHandler(FireOnMouseDown);
control.MouseUp += new MouseEventHandler(FireOnMouseUp);
control.MouseMove += delegate(object sender, MouseEventArgs e)
{
if (Dragging)
{
if (direction != Direction.Vertical)
container.Left = Math.Max(0, e.X + container.Left - DragStart.X);
if (direction != Direction.Horizontal)
container.Top = Math.Max(0, e.Y + container.Top - DragStart.Y);
}
};
}
注意:第三个订阅是他们之前的(匿名代表)。我相信我需要在事件中传递正确的控制权。这是否更清楚我的问题?
答案 0 :(得分:2)
回答这个问题:
然而,在这部分我得到的错误“一个参考是 非静态字段,方法或属性所需要的“等等 blah.OnMouseDown “”
Init
方法是静态的,这意味着在其中使用的任何非局部变量必须是静态的。在您的代码中,public event MouseDown OnMouseDown;
必须是静态的。
只需执行此操作即可正常工作(无需委托):
修改强> 请参阅下面的代码,了解如何获取已单击的控件。
public static void Init(Control control, Control container, Direction direction)
{
control.MouseDown += new System.Windows.Forms.MouseEventHandler(On_MouseDown);;
}
private static void On_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
Control control = sender as Control;
if(control != null){
// Here we go, use the control to do whatever you want with it
}
}
答案 1 :(得分:1)
你应该写:
control.MouseDown += new MouseEventHandler(MouseDownEvent);
这里要小心你必须更改MouseDownEvent的签名,因为Control的MouseDown事件只需要发送者和MouseEventArgs作为参数。
但我不确定这是不是你真正想要的。该指令的作用是当鼠标在控件上关闭时,执行MouseDownEvent。这是你想要的吗?
指令public event MouseDown OnMouseDown;
是无效的,除非在同一个类中的某个地方出现这样的情况,你不会写出以这种方式触发此事件的内容:
if (OnMouseDown!= null)
OnMouseDown(aSenderObject, aMouseEventArgs, aControl);
要订阅thgis事件,你应该写这个(这里hc anObj是定义事件的类的实例):
anObj.OnMouseDown+= new MouseDown(MouseDownEvent);
希望它有所帮助。也许更多的背景可能有用。
编辑:
如果您正在尝试实现一个管理控件移动的类,您可以使用包含以下内容的Helper类:
public delegate void MouseDown(object sender, MouseEventArgs e, Control control);
public static event MouseDown OnMouseDown;
如果您希望能够将控件“注册”到您的班级,则可以这样做(请注意,该事件是静态的)。在这里,您可以说当鼠标在控件上关闭时,会执行FireMouseDown。
public static void Init(Control control, Control container, Direction direction)
{
control.MouseDown += new MouseEventHandler(FireOnMouseDown);
}
在FireMouseDown中,您必须使用正确的参数触发OnMouseEvent:
public static void FireOnMouseDown(object sender, MouseEventArgs e)
{
if (OnMouseDown != null)
OnMouseDown(this, e, sender as Control);
}
现在,您可以从Helper外部订阅OnMouseDown原始方法:
Helper.OnMouseDown += new MouseDown(MouseDownEvent);
EDIT2:
我没有指定它,但是这里发生的是每次在传递给Init的其中一个控件上有一个MouseDown事件(我的意思是windows事件)时会触发OnMouseDown事件。这意味着OnMouseDown的注册只需要进行一次。之后,每次在其中一个控件上有MouseDown时,会通过以下参数执行MouseDownEvent:
sender -> the Helper class
e -> the original MouseEventArgs generated by Windows
control -> the control that generated the original event
关于MouseMove事件,你应该做类似于MouseDown的事情,只需添加你需要的额外参数(即使我不清楚容器和方向的含义是什么,因为看起来容器总是相等的控制和方向始终是Direction.Any)。我的意思是:
public delegate void MouseMove(object sender, MouseEventArgs e, Control control, Control container, Direction direction);
public static event MouseMove OnMouseMove;
public static void FireOnMouseMove(object sender, MouseEventArgs e)
{
if (OnMouseMove != null)
OnMouseMove(this, e, sender as Control, aContainer, aDirection);
}
我在这里不明白的是从哪里找到aContainer和aDirection。如果我应该复制你的Init我会写OnMouseMove(this, e, sender as Control, sender as Control, Direction.Any);
,但我不认为它会起作用。