Detect which ChartArea is being double-clicked

2019-08-11 08:24发布

问题:

I have a chart (myChart) and more ChartArea in MyArea that is the ChartAreasCollection. I have to determinate if a double click is made in a certain ChartArea of the collection for select it. With the code written below every ChartArea has the same values for limits (x,y) so the if-condition is always true, even if the click was done on the first area.

Every chartarea can be visible or not so for use this function I have to check with the counter ActiveAreas if are visible more then one.

private void chartInForm_DoubleClick(object sender, EventArgs e)
{
    if (ActiveAreas > 1)
    {
        Point mouse = ((MouseEventArgs)e).Location;

        foreach (ChartArea ca in MyArea)
        {
            if (mouse.X > ca.Position.X &&
                mouse.X < ca.Position.X + ca.Position.Width * myChart.Width / 100 &&
                mouse.Y > ca.Position.Y &&
                mouse.Y < ca.Position.Y + ca.Position.Height * myChart.Height / 100)
            MessageBox.Show(ca.Name);
        }

    }
}

回答1:

This should help:

private void chartInForm_MouseDoubleClick(object sender, MouseEventArgs e)
{
    foreach(ChartArea ca in chartInForm.ChartAreas)
    {
        if (ChartAreaClientRectangle(chartInForm, ca).Contains(e.Location))
        { 
            Console.WriteLine(" You have double-clicked on chartarea " +  ca.Name; 
            break; 
        }
    }
}

The key is using Position.ToRectangleF when calculating the pixel positions of the CAs; it will bring back the result even when the ChartArea is positioned automatically..:

RectangleF ChartAreaClientRectangle(Chart chart, ChartArea CA)
{
    RectangleF CAR = CA.Position.ToRectangleF();
    float pw = chart.ClientSize.Width / 100f;
    float ph = chart.ClientSize.Height / 100f;
    return new RectangleF(pw * CAR.X, ph * CAR.Y, pw * CAR.Width, ph * CAR.Height);
}

Note that invisible ChartAreas by default will not be clicked nor will they take up space and the others will move to their place. But if you set fixed positions this may change and you may indeed need to add a check for ca.Visible ...