0

I have TableLayoutPanel on windows form. I want mouse pointer cursor style is cross when the pointer on/near the cell border.

Edit I tried with mouse move event. I get the cell positions where the mouse point is moving.But I couldn't use this information and I was stuck. How can achieve that?

Edit: I fixed the problem. It is about size type. The code is working. I'm sharing it for those who have similar demands. Thanx.

bool calcCells = false;
List<float> XCoordinates = new List<float>();
List<float> YCoordinates = new List<float>();  
    
public Form3()
{
    InitializeComponent();
    // Set the DoubleBuffered property via reflection (if needed)
    var flags = BindingFlags.Instance | BindingFlags.NonPublic;
    tlp1.GetType().GetProperty("DoubleBuffered", flags).SetValue(tlp1, true);
    tlp1.Layout += tlp1_Layout;
    tlp1.CellPaint += tlp1_CellPaint;
    tlp1.MouseMove += tlp1_MouseMove;
}

// Added the x coordinates of cell borders in a List
private void CreateXCoordinateList()
{
    XCoordinates.Clear();

    //  first  and last column sizetype is SizeType.Absoulute.
    float tlpWidth = tlp1.Width- tlp1.ColumnStyles[0].Width - tlp1.ColumnStyles[tlp1.ColumnCount-1].Width;
    float x = 0;
    for (int i = 0; i < tlp1.ColumnCount; i++)
    {
        if(tlp1.ColumnStyles[i].SizeType==SizeType.Absolute)
        x += tlp1.ColumnStyles[i].Width;
        else if(tlp1.ColumnStyles[i].SizeType == SizeType.Percent)
        {
            double k = tlpWidth * tlp1.ColumnStyles[i].Width * 0.01;
            x += Convert.ToSingle(k);
        }
        XCoordinates.Add(x);
    }
}

// Added the y coordinates of cell borders in a List
private void CreateYCoordinateList()
{
    YCoordinates.Clear();

    //  first  and last row sizetype is SizeType.Absoulute.
    float tlpHeight = tlp1.Height - tlp1.RowStyles[0].Height - tlp1.RowStyles[tlp1.RowCount - 1].Height;
    float y = 0;
    for (int i = 0; i < tlp1.RowCount; i++)
    {
        if (tlp1.RowStyles[i].SizeType == SizeType.Absolute)
            y += tlp1.RowStyles[i].Height;
        else if (tlp1.RowStyles[i].SizeType == SizeType.Percent)
        {
            double k = tlpHeight * tlp1.RowStyles[i].Height*0.01;
            y += Convert.ToSingle(k);
        }
        YCoordinates.Add(y);
    }
}



private void tlp1_Layout(object sender, LayoutEventArgs e) => calcCells = true;

private void tlp1_CellPaint(object sender, TableLayoutCellPaintEventArgs e)
{
    if (calcCells)
    {
        CreateXCoordinateList();
        CreateYCoordinateList();
        if (e.Column == tlp1.ColumnCount - 1 &&
            e.Row == tlp1.RowCount - 1) 
            calcCells = false;
    }
}
private void tlp1_MouseMove(object sender, MouseEventArgs e)
{
    //Comparing the mouse pointer position with the cellborder coordinates,
    //if the difference is less than and equal to 4, change the cursor style.
    float x = e.Location.X;
    float y = e.Location.Y;
    if (MouseNearCellBorderXAxis(e) || MouseNearCellBorderYAxis(e))
        tlp1.Cursor = Cursors.Cross;
    else
        tlp1.Cursor = Cursors.Default;
}
private bool MouseNearCellBorderXAxis(MouseEventArgs e)
{
    float x = e.Location.X;
    for (int i = 0; i < XCoordinates.Count; i++)
    {
        float Border = XCoordinates[i];
        double difference = Math.Abs(x - Border);
        if (difference <= 4)
            return true;
        
    }
    return false;
}
private bool MouseNearCellBorderYAxis(MouseEventArgs e)
{
    float y = e.Location.Y;
    for (int i = 0; i < YCoordinates.Count; i++)
    {
        float Border = YCoordinates[i];
        double difference = Math.Abs(y - Border);
        if (difference <= 4)
            return true;
        
    }
    return false;
}
Gokhan
  • 453
  • 4
  • 10
  • 1
    Read (again) the notes and related methods here: [Capture image of specific area of a TableLayoutPanel](https://stackoverflow.com/a/68238487/7444103) – Jimi Feb 09 '23 at 15:04
  • Thanx again @Jimi. Actually i used your infos. I tried to catch from coordinates of cell border and mouse pointer. But I guess I'm missing the detail during the comparison with coordinates. I shared the codes ablove. Could you look at? – Gokhan Feb 10 '23 at 07:25

1 Answers1

1

If I get what you're asking, provided you have controls in the cells of the TableLayoutPanel all one would have to do is set the different cursors one time for:

  • Main form (Arrow)
  • Table layout panel (Cross)
  • The controls therein contained (e.g. Hand)

screenshot

Everything else should happen on its own.

public MainForm()
{
    InitializeComponent();

    // MainForm has ARROW
    this.Cursor = Cursors.Arrow;

    // TableLayoutPanel has CROSS
    tableLayoutPanel.Cursor = Cursors.Cross;

    int key = 0; string text;
    for (int column = 0; column < tableLayoutPanel.ColumnCount; column++)
        for (int row = 0; row < tableLayoutPanel.RowCount; row++)
        {
            switch (++key)
            {
                case 10: text = "*"; break;
                case 11: text = "0"; break;
                case 12: text = "#"; break;
                default: text = $"{key}";  break;
            }
            tableLayoutPanel.Controls.Add(new Label
            {
                BackColor = Color.LightGreen,
                Anchor = (AnchorStyles)0xF,
                Margin = new Padding(10),  
                Text = text,
                TextAlign = ContentAlignment.MiddleCenter,

                // Controls in the table have HAND
                Cursor = Cursors.Hand,
            });
        }
}
IVSoftware
  • 5,732
  • 2
  • 12
  • 23
  • Mayn thanx but I want to do this regardless of any control. I shared the codes above. I'm having trouble with coordinate matching. – Gokhan Feb 10 '23 at 05:45
  • 1
    Thanks for letting me know that! Check out this answer by LarsTech it might be just what you need https://stackoverflow.com/a/20858985/5438626 only you would look at the mouse _move_ instead of the mouse _click_ of course. – IVSoftware Feb 10 '23 at 12:55