我有几个代表人的复选框。像这样:
[ ] George
[ ] Sam
[ ] Steve
[ ] Lisa
每个都可以单独检查,当然也可以根本不检查。代码在检查状态发生变化时运行。该代码使用其算法中所有复选框的状态。
然而,我希望他们在双击时表现得像radiobuttons。也就是说,如果你双击一个,它应该被检查(不管它以前的状态如何),所有其他的将被取消检查。
不幸的是,复选框没有双击事件。很明显,我需要通过使用mousedown(或鼠标向上)以及计时器,秒表等的组合来模拟双击。
最终我知道我会通过实验找到解决方案,所以如果我想出一个好的解决方案,我会在这里发布。但我感觉其他人之前有“模拟双击”,如果有人可以发布一个好的片段来从mousedown事件中创建这样的事件,那就太棒了。
P.S。该片段应以某种方式涉及SystmInformation.DoubleClickTime
。 (这是区分doubleclick与“two singleclicks”的毫秒数。从一台机器到另一台机器可能会有所不同。)单击的代码不应该运行,直到经过很长时间,以确保双击不是等待。 (因为正如我所提到的,代码使用了所有复选框的状态。)
P.P.S。我正在使用VB.NET Express 2008作为winforms应用程序,但我可以根据需要翻译C#,我认为这可能适用于所有.NET平台。
答案 0 :(得分:2)
复选框确实有DoubleClick事件。
<强> CheckBox Class 强>
DoubleClick 基础设施。用户双击CheckBox时发生 控制。
修改强>
如评论中所述,默认行为是不调用该事件。
你可以做的是创建自己的继承自CheckBox的类
您需要设置 StandardDoubleClick 样式。使用 SetStyle() 方法。
然后在引发事件之前覆盖 OnDoubleClick 方法以捕获它。
public class MyCheckBox : CheckBox {
MyCheckBox()
{
this.SetStyle(ControlStyles.StandardDoubleClick);
}
protected override void OnDoubleClick(EventArgs e)
{
Base.OnDoubleClick(e);
//Do what ever you want... Like actually calling the DoubleClick event....
}
}
答案 1 :(得分:2)
好的,最后一个例子不起作用,你是对的; DoubleClick活动永远不会被提出。所以,这可能有点“hacky”,但会奏效:
扩展CheckBox
类,例如创建一个CheckboxExtended
类。在这个类中,我们覆盖WndProc
方法并拦截windows双击消息。示例代码如下:
public class CheckBoxExtended : CheckBox
{
private const int WM_LBUTTONDBLCLK = 0x203;
protected override void WndProc(ref Message m)
{
// Threat the message first
if (m.Msg == WM_LBUTTONDBLCLK)
{
var lparam = m.LParam.ToInt32();
var x = lparam & 0x0000FFFF;
var y = (int) ((lparam & 0xFFFF0000) >> 16);
OnMouseDoubleClick(new MouseEventArgs(MouseButtons.Left, 2, x, y, 0));
}
base.WndProc(ref m);
}
}
我仍然不确定解析LParam以获得鼠标位置。请给我几秒钟。
要使用该课程,请按照我之前的说法进行操作:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
checkBoxExtended1.MouseDoubleClick += new MouseEventHandler(checkBoxExtended1_MouseDoubleClick);
}
void checkBoxExtended1_MouseDoubleClick(object sender, MouseEventArgs e)
{
MessageBox.Show(@"Test");
}
}
当然,我假设一张表格上有CheckBoxExtended
。
编辑:哎呀,我刚刚发现我使用的是二进制文件,而不是二进制文件。现在源是固定的,应该返回正确的坐标。
编辑2:好的,我已经在VB中创建了这个类,但我没有测试过它 - 我在VB中的技能也不是那么好。一个提示:您可以自己为扩展类编写另一个DoubleClick事件,并添加必要的装饰(属性)以使Designer能够显示它。
Public Class CheckboxExtended
Inherits CheckBox
Private Const WM_LBUTTONDBLCLK As Integer = &H203
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
'Threat the message first
If m.Msg = WM_LBUTTONDBLCLK Then
Dim lparam = m.LParam.ToInt32()
Dim x = lparam And &HFFFF
Dim y = ((lparam And &HFFFF0000) >> 16)
OnMouseDoubleClick(New MouseEventArgs(MouseButtons.Left, 2, x, y, 0))
End If
MyBase.WndProc(m)
End Sub
End Class
答案 2 :(得分:2)
需要进行手术,编写CheckBox类以假定标准的单击和双击行为已关闭。这段代码有效,你将不得不放弃MouseUp事件:
Imports System.ComponentModel
Public Class MyCheckBox
Inherits CheckBox
Public Sub New()
Me.SetStyle(ControlStyles.StandardClick Or ControlStyles.StandardDoubleClick, True)
End Sub
Protected Overrides Sub OnMouseUp(ByVal mevent As System.Windows.Forms.MouseEventArgs)
'' NOTE: do *not* call the base method
MyBase.ResetFlagsandPaint()
End Sub
<EditorBrowsable(EditorBrowsableState.Always), Browsable(True)> _
Public Shadows Custom Event DoubleClick As EventHandler
AddHandler(ByVal value As EventHandler)
AddHandler MyBase.DoubleClick, value
End AddHandler
RemoveHandler(ByVal value As EventHandler)
RemoveHandler MyBase.DoubleClick, value
End RemoveHandler
RaiseEvent(ByVal sender As Object, ByVal value As EventArgs)
Throw New InvalidOperationException '' should never be raised by user code
End RaiseEvent
End Event
End Class
事件处理程序可能如下所示:
Private Sub MyCheckBox_DoubleClick(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles MyCheckBox1.DoubleClick, MyCheckBox2.DoubleClick, MyCheckBox3.DoubleClick, MyCheckBox4.DoubleClick
For Each box As CheckBox In GroupBox1.Controls
box.Checked = box.Equals(sender)
Next
End Sub
可能有一些手术副作用,我没有看到任何但没有彻底测试。我建议你不实际上这样做,这个功能是大规模不可发现的。没有用户会意识到双击现在可以做一些特别的事情。