通过反射设置winform面板名称时,将visible设置为true会失败。为什么?

时间:2015-08-08 16:48:38

标签: c# winforms reflection

我试图遍历许多默认设置为.Visible = false的面板。我想将这些更改为true,但我只会在运行时知道哪些。

我有以下代码:

var genericPanel =  new Panel();
            var myName = "panel" + i;
            PropertyInfo prop = genericPanel.GetType().GetProperty("Name", BindingFlags.Public | BindingFlags.Instance);
            if (null != prop && prop.CanWrite)
            {
                prop.SetValue(genericPanel, myName, null);
            }

            genericPanel.Enabled = true;
            genericPanel.Visible = true;
            var blah = genericPanel.Name;  // Name is correct
            Application.DoEvents();

            // This works fine
            //panel1.Visible = true;
            //panel1.Enabled = true;
            //Application.DoEvents();

使用反射我似乎能够正确设置对象名称,但我尝试设置可见性和启用的属性失败。这样做可以直接使用。

我错过了什么?

2 个答案:

答案 0 :(得分:0)

您需要将面板添加到表单(或某些容器)控件中。

您可能已经有一个令您困惑的面板1:

var genericPanel = new Panel();
var myName = "panel" + 3;
PropertyInfo prop = genericPanel.GetType().GetProperty("Name", BindingFlags.Public | BindingFlags.Instance);
if (null != prop && prop.CanWrite)
{
    prop.SetValue(genericPanel, myName, null);
}
genericPanel.Enabled = true;
genericPanel.Visible = true;
genericPanel.BackColor = Color.Red;

this.Controls.Add(genericPanel);

答案 1 :(得分:0)

我认为您不需要使用System.Reflection。你在代码中创建了一个错误的新面板。您应该执行以下操作:

private void SetControlVisibility(string controlName, bool visible)
{
    // Searches through all controls inside your Form recursively by controlName
    Control control = GetControlByName(this.Controls, controlName);

    if (control != null)
        control.Visible = visible;
}

private Control GetControlByName(Control.ControlCollection controls, string controlName)
{
    Control controlToFind = null;

    foreach (Control control in controls)
    {
        // If control is container like panel or groupBox, look inside it's child controls
        if (control.HasChildren)
        {
            controlToFind = GetControlByName(control.Controls, controlName);

            // If control is found inside child controls, break the loop
            // and return the control
            if (controlToFind != null)
                break;
        }

        // If current control name is the name you're searching for, set control we're
        // searching for to that control, break the loop and return the control
        if (control.Name == controlName)
        {
            controlToFind = control;
            break;
        }
    }

    return controlToFind;
}

用例示例:

int i = 3;
string controlName= "panel" + i; // I'm hiding green panel (panel3)
SetControlVisibility(controlName, false);

<强>之前:

Before

<强>后:

After

修改

根据评论中的建议,您还可以使用Find Control.ControlCollection方法。它看起来像这样:

// True flag is to search through all nested child controls
Control[] controls = this.Controls.Find(panelName, true);
if (controls != null)
    controls[0].Visible = false;