对象上的自定义单击事件(类Cell)仅在您单击时触发最后一个单元格

时间:2014-07-04 09:15:44

标签: c# winforms events

大家好,这是我的第一个问题。 我在单元类上正确创建自定义创建的click事件时遇到了一些问题。到目前为止,它通知何时单击单元格,但它仅显示单击最后一个单元格,即使您单击第一个单元格。这是我的代码。

class Cell 
{
    public const int Width = 220;
    public const int Height = Width;
    public Point Position { get; set; }
    public string  Id { get; set; }

    public delegate void ClickEvent(object o);
    public event ClickEvent Click;


    public Cell()    
    {     

    }

    public void OnClick(Point p)
    {
        if (Click != null)
        {

            if (p.X - 220 < Position.X && p.X > 200 && p.Y - 220 < Position.Y && p.Y > 10)
            {
                Click(this);
            }

        }
    }

    public override string ToString() { return "Cell(" + row + "," + col + ")"; }
    }  


public partial class Form1 : Form
{
    Grid myGrid;
    Cell cell;
    private Point userPoint;
    Graphics g;
    int x = 200;
    int y = 20;

    public Form1()
    {
        InitializeComponent();
        myGrid = new Grid();         
    }
    private void Form1_MouseDown(object sender, MouseEventArgs e)
    {
        userPoint = e.Location;
        cell.OnClick(userPoint);
        label1.Text = userPoint.ToString();
    }

    private void Form1_Paint(object sender, PaintEventArgs e)
    {
        g = e.Graphics;
        DrawCrossingCells();
        myGrid.DrawAllCrossings(g,imageList1);
    }

    private void DrawCrossingCells()
    {

        for (int row = 0; row < 3; row++)
        {
            for (int col = 0; col < 4; col++)
            {
                cell = new Cell(row,col);                   
                g.DrawRectangle(new Pen(Color.Blue),x,y,Cell.Width,Cell.Height);
                cell.Position = new Point(x, y);
                cell.Id = (col.ToString() + row.ToString()).ToString();
                x += 220;
                cell.Click += cell_Click;               
            }             
            x = 200;
            y += 220;
        }
    }

    private void cell_Click(object sender)
    {
        Cell cc = (Cell)sender;
        Crossing cross = new Crossing(cc.Id);
        cross.Position = cc.Position;
        myGrid.AddCrossing(cross);
        MessageBox.Show(cc.Id);
    }
}

1 个答案:

答案 0 :(得分:0)

Cell的循环的每次迭代中,只有一个DrawCrossingCells对象被覆盖。这意味着cell字段只指向循环中创建的最后Cell,因此当您执行cell.OnClick(userPoint);时,您始终会调用上次创建的OnClick Cell }}

您需要在Cell创建对象时存储每个Form1对象。对于行中的每个Listcell对于每行ListList是有意义的。这意味着行Cell cell;将成为List<List<Cell>> cells = new List<List<Cell>>();。在循环中,您可以使用您创建的每个cells填充Cell对象。

Form1_MouseDown中,您需要确定哪些Cell已被点击,并在正确的OnClick上调用e.Location.X。这可以通过将List除以220(单元格宽度)并将其用作内部e.Location.Y的索引并将List除以220(单元格高度)并使用它来完成索引外private void DrawCrossingCells() { for (int row = 0; row < 3; row++) { List<Cell> rowCells = new List<Cell>(); for (int col = 0; col < 4; col++) { Cell cell = new Cell(row, col); g.DrawRectangle(new Pen(Color.Blue), x, y, Cell.Width, Cell.Height); cell.Position = new Point(x, y); cell.Id = (col.ToString() + row.ToString()).ToString(); x += 220; cell.Click += cell_Click; rowCells.Add(cell); } cells.Add(rowCells); x = 0; y += 220; } } private void Form1_MouseDown(object sender, MouseEventArgs e) { int row = e.Location.Y / 220; //divide by the Y size int column = e.Location.X / 220; //divide by the X size cells[row][column].OnClick(e.Location); label1.Text = e.Location.ToString(); }

两个更改方法的代码将是:

{{1}}