如何在工具提示处于c#时检查鼠标单击

时间:2016-11-27 10:52:18

标签: c# visual-studio

在我的代码生成的下图中,

我希望工具提示在我的光标位于其上时显示每种颜色的值,当我点击图像上的特定位置时,我想在图像上显示虚线。

Ref Bar Image 这是我的代码:



RefBar.MouseMove += new MouseEventHandler(RefBar_MouseMove);
            RefBar.MouseClick += new MouseEventHandler(RefBar_Click);

private void RefBar_MouseMove(object sender, MouseEventArgs e)
         {  
             if (gotMapFirstTime == true)
             {
                 Point LocalMousePosition = RefBar.PointToClient(System.Windows.Forms.Cursor.Position);
                 MousePointDisplay.SetToolTip(RefBar, WaferMap.getParamValueFromMousePointerXY(LocalMousePosition.X, LocalMousePosition.Y, 1, true).ToString());                  
             }
         }

private void RefBar_Click(object sender, EventArgs e)
        {
            byte[] bytes2;
            Image image;
            MouseEventArgs me = (MouseEventArgs)e;
            Point coordinates = me.Location;
            
            WaferMap.RefBarDashLines.Add(coordinates.Y);
            
            int[] rfd = WaferMap.RefBarDashLines.ToArray();
            if (rfd.Length > 2)
            {
                RefBar.Image.Dispose();
                bytes2 = WaferMap.CreateMapReferenceBar(40, 580, 0, 0, 1);
                WaferMap.RefBarDashLines = new List<int>();
                WaferMap.UpperTrackBarLimit = 0.0;
                WaferMap.LowerTrackBarLimit = 0.0;
                pictureBox2.Image.Dispose();
                bytes2 = WaferMap.CreateGridImage(120, 120, 9, 9, 5);
                image = Image.FromFile(WaferMapImage);
                pictureBox2.Image = image;
            }
            else if(rfd.Length == 2)
            {
                RefBar.Image.Dispose();
                bytes2 = WaferMap.CreateMapReferenceBarByClick(40, 580, 0, 0, 1);
                pictureBox2.Image.Dispose();
                bytes2 = WaferMap.CreateGridImageFilteredByTrackBar(120, 120, 9, 9, 5);
                image = Image.FromFile(WaferMapImage);
                pictureBox2.Image = image;
            }
            else
            {
                RefBar.Image.Dispose();
                bytes2 = WaferMap.CreateMapReferenceBarByClick(40, 580, 0, 0, 1);
            }
            
            image = Image.FromFile(ReferenceBarImage);
            RefBar.Image = image;
            
            MapLowerLimit.Text = coordinates.X.ToString() + " " + coordinates.Y.ToString();
        }
&#13;
&#13;
&#13;

在类wafermap中我们有这个:

&#13;
&#13;
 public static double getParamValueFromMousePointerXY(int x, int y, int boxSize, bool isRefBarOrHistogram)
        {
            double returnVal = 0.0;
            Point UL;
            Point BR;
            int cellX;
            int invertY;
            int cellY;
            if (isRefBarOrHistogram)
            {
                invertY = -1*(y - RefBarLength);
                return get_YCell_to_ParamValue(invertY, RefBarLength);
            }
            else
            {
                foreach (die dd in dieList)
                {
                    cellX = dd.col;
                    cellY = dd.row;
                    UL = new Point(boxSize * (cellX + 2), boxSize * (cellY + 4));
                    BR = new Point((boxSize * (cellX + 2)) + boxSize, (boxSize * (cellY + 4)) + boxSize);
                    if ((UL.X < x && x <= BR.X) && (UL.Y < y && y <= BR.Y))
                    {
                        return dd.ParamValue;
                    }

                }
            }
           
            return returnVal;
        }
public struct die
{
    public int row;
    public int col;
    public int site;
    public string param;
    public double ParamValue;
}
&#13;
&#13;
&#13;

如果工具提示功能被注释掉,鼠标单击事件的代码可以正常工作,但是当为鼠标移动功能调用工具提示功能时,代码在多次单击鼠标点击事件后无法检测或检测到,我该如何操作纠正这个?

1 个答案:

答案 0 :(得分:1)

您的问题可能是getParamValueFromMousePointerXY执行时间过长导致您的UI线程被阻止执行任何其他任务,例如处理您的点击。

您可以将工作卸载到后台任务并编组将工具提示设置回UI线程:

Task.Run(() => {
    string paramValue = WaferMap.getParamValueFromMousePointerXY(LocalMousePosition.X, LocalMousePosition.Y, 1, true).ToString();
    MethodInvoker setTooltip = delegate() {
        MousePointDisplay.SetToolTip(RefBar, paramValue);
    };
    RefBar.Invoke(setTooltip);
});

你在这里做的是在后台任务中执行getParamValueFromMousePointerXY,同时继续在UI线程中执行SetToolTip

这里唯一需要注意的是,你可能会在这里运行很多后台任务,这些任务将处于竞争状态以设置工具提示。您可以使用取消令牌来防止这种情况。您为CancellationTokenSource定义了一个变量:

CancellationTokenSource tooltipSource = null;

您可以使用此取消令牌来源来阻止对工具提示的旧更新:

tooltipSource?.Cancel();
tooltipSource = new CancellationTokenSource();

Task tooltipTask = new Task((tokenObj) => {
    string paramValue = WaferMap.getParamValueFromMousePointerXY(LocalMousePosition.X, LocalMousePosition.Y, 1, true).ToString();
    ((CancellationToken)tokenObj).ThrowIfCancellationRequested();
    MethodInvoker setTooltip = delegate() {
        MousePointDisplay.SetToolTip(RefBar, paramValue);
    };
    RefBar.Invoke(setTooltip);
}, tooltipSource.Token);
tooltipTask.Start();

有了这个,你应该减少工具提示的更新次数。

当然,您可以将CancellationToken传递给getParamValueFromMousePointerXY并更早取消任务。