如何在C#中显示一个用户控件并隐藏其他控件。

3

我是C#的新手,正在使用Windows Forms。

我有一个名为Form1的窗体,其中包含20个按钮(buttons)和20个用户控件(user controls)。我的目标是:

当我点击button1时,user control1将显示出来,其他user controls将隐藏;当我点击button2时,user control2将显示出来,其他user controls将隐藏;当我点击button3时,user control3将显示出来,其他user controls将隐藏,以此类推。我可以使用UserControl.visible = True来显示一个user control并通过设置其他user controls visibility = False来隐藏其余部分,但是我不想写太多代码。

所以我使用了以下简单的代码来在相关的button被点击时只显示一个user control并隐藏其余的user controls,但这段代码没有起作用,虽然没有出现错误,但user controls仍然可见。

有人知道为什么这段代码没有显示一个user control并隐藏其余部分吗?我也很乐意听取其他的想法。谢谢!

private void button1_Click(object sender, EventArgs e) 
{
    foreach (Control ctrl in this.Controls)
    {
        if (ctrl .GetType() == typeof(UserControl))
        {
            ctrl .Visible = false;
        }
    }
    UserControl1.visible = True;
}

可能是因为它是一个嵌套控件。目前,您的循环仅遍历顶部控件。如果一个 control.Controls 不为空,则会忽略这些子控件。您可以使用递归方法。您使用过调试器吗?ctrl.Visible = false 是否被执行了? - Tim Schmelter
不要使用 ctrl.Visible = false;,可以使用 ctrl.IsVisible = false; - Jamaxack
3个回答

5
你的代码未按预期工作的原因是这个条件:
if (ctrl.GetType() == typeof(UserControl))

GetType() 返回的是实际类型,它永远不会是 UserControl,而是从它派生出来的一些类型。

请改用以下方法:

if (ctrl is UserControl)

3

Button有一个属性Tag。在所有按钮的标签属性中保存您的UserControl引用:

button1.Tag = UserControl1;
button2.Tag = UserControl2;
button3.Tag = UserControl3;
//and so on...
//you can do it FormLoad event handler

现在将所有按钮订阅到单个“点击”事件中:
button1.Click += button1_Click; //I am using "button1_Click" for all buttons
button2.Click += button1_Click;
button3.Click += button1_Click;

现在重点在这里:
private void button1_Click(object sender, EventArgs e) 
{
    Button btn = sender as Button;  //cast the sender

    //hide all user controls
    foreach (Control ctrl in this.Controls)
    {
        if (ctrl .GetType() == typeof(UserControl))
        {
            ctrl .Visible = false;
        }
    }

    //show the usercontrol saved in "Tag" of the current button
    (btn.Tag as UserControl).Visible = True;
}

Note: 我没有编译过这段代码,如果您遇到任何错误,请告诉我。


或者您可以给按钮和用户控件打上数字标签(1、2、3等),并隐藏除与匹配标签相同的用户控件之外的所有用户控件(userControl.Tag == (sender as Button).Tag)。 - CompuChip
是的,那也可以。但主要的重点是使用一个事件处理程序来处理所有按钮。 - Shaharyar

2
这段代码对我很有效:

    var pairs = new[]
    {
        new { Button = button1, UserControl = userControl1 },
        new { Button = button2, UserControl = userControl2 },
        new { Button = button3, UserControl = userControl3 },
        new { Button = button4, UserControl = userControl4 },
        new { Button = button5, UserControl = userControl5 },
        new { Button = button6, UserControl = userControl6 },
        new { Button = button7, UserControl = userControl7 },
        new { Button = button8, UserControl = userControl8 },
        new { Button = button9, UserControl = userControl9 },
        new { Button = button10, UserControl = userControl10 },
        new { Button = button11, UserControl = userControl11 },
        new { Button = button12, UserControl = userControl12 },
        new { Button = button13, UserControl = userControl13 },
        new { Button = button14, UserControl = userControl14 },
        new { Button = button15, UserControl = userControl15 },
        new { Button = button16, UserControl = userControl16 },
        new { Button = button17, UserControl = userControl17 },
        new { Button = button18, UserControl = userControl18 },
        new { Button = button19, UserControl = userControl19 },
        new { Button = button20, UserControl = userControl20 },
    };

    foreach (var pair in pairs)
    {
        pair.UserControl.Visible = false;
        pair.Button.Click += (s, e2) =>
        {
            foreach (var pair2 in pairs) { pair2.UserControl.Visible = false; }
            pair.UserControl.Visible = true;
        };
    }

我会有意地创建一个按钮/用户控件对的列表,这样它们就是硬编码的,我不需要通过名称查找它们。这样做对于重构和验证代码来说更好。

然后第一个foreach循环只是连接了点击事件,使得除了配对的用户控件之外所有的用户控件都不可见。

只需要将此代码放入您的Form_Load事件处理程序中即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接