根据我从其他答案中学到的知识,我能够做到这一点。我在这里发布解决方案,以防其他人需要它。
我创建了一个组件MouseDownManager,我在MouseDown事件期间调用它。它跟踪刚刚按下的按钮,确定我们正在等待的按钮,以便拥有“两个”按钮按下事件,然后启动一个定时器以等待该按钮。如果在分配的时间内,按下了正确的按钮,则MouseDownManager引发相应的“两个”按钮向下事件。否则,它会引发相应的单个按钮事件。在窗体上,我正在处理MouseDownManager的MouseDown事件以对翻译的鼠标单击进行操作。
我现在可以将这个组件放在窗体/控件上,然后我可以对“双方”单击作出反应。
感谢您的帮助解决这个问题。
/// <summary>
/// Manage mouse down event to enable using both buttons at once.
/// I.e. allowing the pressing of the right and left mouse
/// buttons together.
/// </summary>
public partial class MouseDownManager : Component
{
/// <summary>
/// Raised when a mouse down event is triggered by this
/// component.
/// </summary>
public event EventHandler<MouseEventArgs> MouseDown;
protected virtual void OnMouseDown(MouseEventArgs e)
{
if (this.MouseDown != null)
{
this.MouseDown(this, e);
}
}
public MouseDownManager()
{
//-- the timer was dropped on the designer, so it
// is initialized by InitializeComponent.
InitializeComponent();
}
/// <summary>
/// Defines the interval that the timer will wait for the other
/// click, in milliseconds.
/// </summary>
public int BothClickInterval
{
get
{
return this.tmrBothInterval.Interval;
}
set
{
this.tmrBothInterval.Interval = value;
}
}
private MouseButtons _virtualButton = MouseButtons.Middle;
/// <summary>
/// Defines the button that is sent when both buttons are
/// pressed. This can be either a single button (like a middle
/// button) or more than one button (like both the left and
/// right buttons.
/// </summary>
public MouseButtons VirtualButton
{
get
{
return _virtualButton;
}
set
{
_virtualButton = value;
}
}
private MouseEventArgs _originalArgs;
/// <summary>
/// Defines the original mouse event arguments that is associated
/// with the original press.
/// </summary>
private MouseEventArgs OriginalArgs
{
get
{
return _originalArgs;
}
set
{
_originalArgs = value;
}
}
private MouseButtons _waitButton = MouseButtons.None;
/// <summary>
/// Defines the button that we are waiting on, for there to be a
/// both button click.
/// </summary>
private MouseButtons WaitButton
{
get
{
return _waitButton;
}
set
{
_waitButton = value;
}
}
/// <summary>
/// Manage a mouse button being depressed.
/// </summary>
/// <remarks>
/// This will instigate one of two actions. If there is no
/// current wait button, this will set the appropriate wait
/// button (if the button pressed was the left button, then we
/// are waiting on the right button) and start a timer. If the
/// wait button is set, but this isn't that button, then the wait
/// button is updated and the timer restarted. Also, this will
/// trigger the waiting event. If it is the wait button, then
/// the appropriate event is raised for a "both" button press.
/// </remarks>
public void ManageMouseDown(MouseEventArgs mouseArgs)
{
//-- Is the the button we are waiting for?
if (mouseArgs.Button == this.WaitButton)
{
//-- Turn off timer.
this.ClearTimer();
//-- Create new mouse event args for our virtual event.
MouseEventArgs bothArgs = new MouseEventArgs(this.VirtualButton
, mouseArgs.Clicks
, mouseArgs.X
, mouseArgs.Y
, mouseArgs.Delta);
//-- Raise the mouse down event.
this.OnMouseDown(bothArgs);
}
else
{
//-- Clear timer
this.ClearTimer();
//-- If we were waiting for a button, then
// fire the event for the original button.
if (this.WaitButton != MouseButtons.None)
{
this.OnMouseDown(this.OriginalArgs);
}
//-- Cache the original mouse event args.
MouseEventArgs newMouseArgs = new MouseEventArgs(mouseArgs.Button
, mouseArgs.Clicks
, mouseArgs.X
, mouseArgs.Y
, mouseArgs.Delta);
this.OriginalArgs = newMouseArgs;
//-- Reset to wait for the appropriate next button.
switch (mouseArgs.Button)
{
case MouseButtons.Left:
this.WaitButton = MouseButtons.Right;
break;
case MouseButtons.Right:
this.WaitButton = MouseButtons.Left;
break;
default:
this.WaitButton = MouseButtons.None;
break;
}
//-- Start timer
this.tmrBothInterval.Enabled = true;
}
}
/// <summary>
/// Raise the event for the button that was pressed initially
/// and turn off the timer.
/// </summary>
private void tmrBothInterval_Tick(object sender, EventArgs e)
{
//-- Turn off the timer.
this.tmrBothInterval.Enabled = false;
//-- Based on the original button pressed, raise
// the appropriate mouse down event.
this.OnMouseDown(this.OriginalArgs);
//-- Clear timer.
this.ClearTimer();
}
/// <summary>
/// Clear the timer and associated variables so we aren't waiting
/// for the second click.
/// </summary>
private void ClearTimer()
{
//-- Turn off the timer.
this.tmrBothInterval.Enabled = false;
//-- Clear the wait button.
this.WaitButton = MouseButtons.None;
//-- Clear the original args
this.OriginalArgs = null;
}
}
/// <summary>
/// Just the mouse code from the control needing the functionality.
/// </summary>
public class MyControl: Control
{
/// <summary>
/// Handle the mouse down event. This delegates the actual event
/// to the MouseDownManager, so we can capture the situation
/// where both buttons are clicked.
/// </summary>
protected override void OnMouseDown(MouseEventArgs e)
{
this.mdmMain.ManageMouseDown(e);
}
/// <summary>
/// Process the mouse down event.
/// </summary>
private void mdmMain_MouseDown(object sender, MouseEventArgs e)
{
//-- Get the reported button state.
MouseButtons mouseButton = e.Button;
//-- Execute logic based on button pressed, which now can include
// both the left and right together if needed....
}
}
伙计。不要去那里。 UI标准的存在是有原因的。你的可用性会受到影响。这听起来比“三重点击”更糟糕 – JohnFx 2009-07-25 21:48:27
@JohnFx任何体面的扫雷克隆都需要双击chording。这是一个有用的例子。 – mbomb007 2016-06-03 15:29:43