我的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事件,单击都有效。我四处寻找解决方案,但是找不到解决我问题的方法。

最佳答案

这是一种怪异的行为,更改图片框的BorderStyle会停止单击传播(在Click事件之前总是出现DoubleClick事件)。

我真的不知道如何正确处理它,但是我们可以做一些破解使该功能正常工作。我们可以在ClickDoubleClick之间引入“滞后”,以使DoubleClickClick之前被检查。

在这里,我们使用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);
        }
    }
}

关于c# - C#中的click和doubleclick事件不起作用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25410226/

10-11 04:21