简体   繁体   中英

TableLayoutPanel GetControlFromPosition does not get non-visible controls. How do you access a non-visible control at a specified position?

I'm using a TableLayoutPanel and I want to get the control at a specific position in the TableLayoutPanel . I want to iterate over the rows and columns of TableLayoutPanel but this question applies equally if I just wanted a single control at a specific row and column.
Unfortunately GetControlFromPosition(int column, int row) only retrieves controls that are visible (that is their Visible property is set to True). This is no good to me as sometimes I want to access a control at a specific position that is not visible and then make it visible.

I have had to resort to iterating over the TableLayoutPanel.Controls collection, and then get the position of each control using GetPositionFromControl(Control control) or GetCellPosition(Control control) until I find the position I want.
(I'm not sure of the difference between GetPositionFromControl and GetCellPosition methods as MS documentation is meagre, but I'll ask that question separately ).

Is there a simpler or cleaner way for me to do this?

better c# method:

public static Control GetAnyControlAt(this TableLayoutPanel panel, int column, int row)
{
    foreach (Control control in panel.Controls)
    {
        var cellPosition = panel.GetCellPosition(control);
        if (cellPosition.Column == column && cellPosition.Row == row)
            return control;
    }
    return null;
}

The best I can come up with is creating an extension method. Create a new module named "Extensions.vb" and add:

Imports System.Runtime.CompilerServices

Public Module Extensions

    <Extension()>
    Public Function GetAnyControlAt(Panel As TableLayoutPanel, Column As Integer, Row As Integer) As Control
        For Each PanelControl As Control In Panel.Controls
            With Panel.GetCellPosition(PanelControl)
                If Column = .Column AndAlso Row = .Row Then Return PanelControl
            End With
        Next
        Return Nothing
    End Function
End Module

Now you can use the following to access the method:

Dim MyControl As Control = TableLayoutPanel1.GetAnyControlAt(Column, Row)

Extension methods add the method to the class that's listed as the first parameter, in this case Panel As TableLayoutPanel , and shuffle the rest of the parameters along.

I found a workaround/hack to use GetControlFromPosition for visible=false, first add the control to the table layout panel and then set visible to false

example:

CheckBox Chk_Tbl_exist = new CheckBox();
Chk_Tbl_exist.Text = "This is a checkbox"; 
TableLayoutPanel.Controls.Add(Chk_Tbl_exist, 0, 1);
Chk_Tbl_exist.Visible = false;

And for c#:

public static class ExtensionMethods
        {
            public static Control GetAnyControlAt(TableLayoutPanel pp, int col, int row)
            {
            bool fnd = false;
            Control sendCC = null;
            foreach (Control cc in pp.Controls)
            {
                if (pp.GetCellPosition(cc).Column == col)
                {
                    if (pp.GetCellPosition(cc).Row == row)
                    {
                        sendCC = cc;
                        fnd = true;
                        break;
                    }
                }
            }

            if (fnd == true)
            {
                return sendCC;
            }
            else
            {
                return null;
            }
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM