Reputation: 3190
I have the following code in my C# application
The first determines what happens when the user double-clicks a picture.
private void pictureDoubleClick(Object sender, EventArgs e)
{
PictureBox picture = (PictureBox)sender;
Console.WriteLine(picture.ImageLocation);
MessageBox.Show("Test");
}
And another one for single click:
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;
}
}
I've called both the functions like so:
box.Click += new System.EventHandler(this.picutureClick);
box.DoubleClick += new System.EventHandler(this.pictureDoubleClick);
However I'm facing a strange bug, the DoubleClick event won't get activated, the only way to make it work is if I comment out the single click. The single click works whether or not I comment or un-comment the Doubleclick event. I looked around for solutions but I couldn't find any that resolved my issue.
Upvotes: 3
Views: 6224
Reputation: 4818
It's a weird behavior, that changing BorderStyle
of a picture box will stop the click to propagate (a Click
event will always raise before DoubleClick
event).
I do not really know how to handle it properly, but we could do some hack to make the feature work. We can introduce a "lag" between a Click
and DoubleClick
to make the DoubleClick
is checked before Click
.
Here we use a Timer
to do the job:
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;
}
}
In the above code, I used an extension method to handle cross-thread property updating:
public static void InvokeIfRequired(this Control c, Action<Control> action)
{
if (c.InvokeRequired)
{
c.Invoke(new Action(() => action(c)));
}
else
{
action(c);
}
}
Edit:
The extension method I used above is to simplify the code written to do cross-thread property update. More details on this topic can be found here: Automating the InvokeRequired code pattern
Here are some details on Extension Method:
An extension method only works if it's declared in a non-generic, non-nested static class. To make it work, you need to declare a new public static class
to hold the method.
// 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);
}
}
}
Upvotes: 2
Reputation: 307
When you change the border of the picture box you're kinda of resetting the click event. That's why it's not working and only toggling the one click event, if you comment the change of the border it'll start working... Sorry but I don't know why this is happening and don't know if it's helpful my information =/
Upvotes: 1