我的C#应用程序中有以下代码
第一个决定用户双击图片时会发生什么。
private void pictureDoubleClick(Object sender, EventArgs e)
{
PictureBox picture = (PictureBox)sender;
Console.WriteLine(picture.ImageLocation);
MessageBox.Show("Test");
}
另一个单击:
private void picutureClick(Object sender, EventArgs e)
{
PictureBox picture = (PictureBox)sender;
if (picture.BorderStyle == BorderStyle.None)
{
picture.BorderStyle = BorderStyle.Fixed3D;
picture.BackColor = Color.Red;
}
else
{
picture.BorderStyle = BorderStyle.None;
picture.BackColor = Color.White;
}
}
我把这两个函数称为:
box.Click += new System.EventHandler(this.picutureClick);
box.DoubleClick += new System.EventHandler(this.pictureDoubleClick);
但是我遇到了一个奇怪的错误,DoubleClick事件不会被激活,唯一让它工作的方法就是我注释掉单击。无论我是否评论或取消评论Doubleclick事件,单击都有效。我四处寻找解决方案,但我找不到任何解决了我的问题。
答案 0 :(得分:2)
这是一种奇怪的行为,更改图片框的BorderStyle
会阻止点击传播(Click
事件将始终在DoubleClick
事件之前提升。
我真的不知道如何正确处理它,但我们可以做一些黑客来使功能正常工作。我们可以介绍一个"滞后"在Click
和DoubleClick
之间,DoubleClick
之前会检查Click
。
我们在这里使用Timer
来完成这项工作:
private Timer _timer;
private PictureBox _sender;
private int _clicks;
public Form1()
{
InitializeComponent();
pictureBox.Click += picutureClick;
pictureBox.DoubleClick += (s, e) =>
{
// do your double click handling
_clicks = 0;
};
// this Interval comes from trail and error, it's a balance between lag and
// correctness. To play safe, you can use SystemInformation.DoubleClickTime,
// but may introduce a bit long lagging after you click and before you
// see the effects.
_timer = new Timer {Interval = 75};
_timer.Tick += (s, e) =>
{
if (_clicks < 2)
{
ClickHandler(_sender);
}
_clicks = 0;
_timer.Stop();
};
}
private void picutureClick(Object sender, EventArgs e)
{
_clicks++;
_sender = (PictureBox) sender;
if (_clicks == 1)
{
_timer.Start();
}
}
private void ClickHandler(PictureBox picture)
{
if (picture.BorderStyle == BorderStyle.None)
{
// this line is not thread safe, but you could comment out the .InvokeIfRequire()
// and uncomment this line to have a look at your form's behavior
//picture.BorderStyle = BorderStyle.Fixed3D;
picture.InvokeIfRequired(c => (c as PictureBox).BorderStyle = BorderStyle.Fixed3D);
picture.BackColor = Color.Red;
}
else
{
// same for this
//picture.BorderStyle = BorderStyle.Fixed3D;
picture.InvokeIfRequired(c => (c as PictureBox).BorderStyle = BorderStyle.None);
picture.BackColor = Color.White;
}
}
在上面的代码中,我使用了一个扩展方法来处理跨线程属性更新:
public static void InvokeIfRequired(this Control c, Action<Control> action)
{
if (c.InvokeRequired)
{
c.Invoke(new Action(() => action(c)));
}
else
{
action(c);
}
}
修改强>
我上面使用的扩展方法是简化为执行跨线程属性更新而编写的代码。有关此主题的更多详细信息,请访问:Automating the InvokeRequired code pattern
以下是扩展方法的一些细节:
扩展方法仅在非泛型非嵌套静态类中声明时才有效。要使其工作,您需要声明一个新的public static class
来保存方法。
// your form class declared here
public partial class Form1 : Form
{
// code omitted here
}
// declare the extension method in this extension class
public static class ControlExtensions
{
public static void InvokeIfRequired(this Control c, Action<Control> action)
{
if (c.InvokeRequired)
{
c.Invoke(new Action(() => action(c)));
}
else
{
action(c);
}
}
}
答案 1 :(得分:1)
更改图片框的边框时,您需要重置点击事件。这就是为什么它没有工作,只切换一次点击事件,如果你评论边界的变化,它将开始工作...抱歉,但我不知道为什么会发生这种情况,不知道这是否有用我的信息= /