Menu

问题 从另一种形式重置按钮颜色。

已加入
2020年3月20日
留言内容
65
编程经验
10+
大家好

我正在构建一个C#winForms应用程序,我的主窗体带有一些按钮作为菜单。我有一个停靠的面板,下面的代码显示了我的表单。

C#:
Form frm = new FrmSetupExchanges
            {
                TopLevel = false,
                ControlBox = false,
                Dock = DockStyle.Fill
            };

PnlContainer.Controls.Add(frm);

当用户单击按钮以显示上述形式时,我更改了按钮的背景色,以便用户可以直观地看到他单击了哪个菜单项。我遇到的问题是,当我关闭表单时,我想将主表单上的按钮颜色重置为正常,但是我不知道该怎么做。我所有的编码经验都是在Visual Basic中进行的,因此只需

Visual Basic:
FrmMain.Cmdsetup.Backcolor = Color.Red

Me.Close

我如何在C#中实现这一目标?
提前谢谢了
AJ
 
由主持人最后编辑:

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,566
地点
悉尼,澳大利亚
编程经验
10+
我建议您不要实际使用 按钮 控件。您可以使用 单选按钮 控制并设置其 外貌 属性 按钮。然后,控件将看起来像常规 按钮 控件,但单击一个将自动使它保持凹陷的状态,同时还释放先前被按下的一个。请注意,与其处理 点击 事件,您将处理 已检查Changed 事件。您将需要测试 已检查 属性来决定是否打开一个表单。您没有特别指出,但您可能还想在以下情况下关闭表单 已检查错误的.
 
已加入
2020年3月20日
留言内容
65
编程经验
10+
谢谢JM

我从没想过要这样做,我希望我早一点的LOL,花大量时间为不同的按下状态进行设计和编码等。现在更改可能会更容易,因为您提到我可以在检查状态时关闭表单是错误的,而不是从表单中执行。但是,出于兴趣,您将如何调用另一种形式的控件?
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,566
地点
悉尼,澳大利亚
编程经验
10+
但是,出于兴趣,您将如何调用另一种形式的控件?
在这种情况下,您不会。正确的做法是,第二种形式引发一个事件,而第一种形式处理该事件,然后进行自我更新。在这种情况下, 表格已关闭 事件已经存在,因此无需声明自定义事件。基本上,当您的第一个表单创建第二个表单时,它会为 表格已关闭 事件,并且在该方法中,它将重置其自身的颜色 按钮.
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,566
地点
悉尼,澳大利亚
编程经验
10+
尝试使用事件选项时,请记住,完成对象操作后还需要删除事件处理程序。您可以使用 发件人 参数以引用对象。例如,如果您注册这样的事件处理程序:
C#:
myObject.SomeEvent += SomeMethod;
然后,在里面 某种方法,您可以这样做:
C#:
((SomeType) sender).SomeEvent -= SomeMethod;
如果不删除事件处理程序,则只要存在处理事件的对象,就无法完成要处理其事件的对象。
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,566
地点
悉尼,澳大利亚
编程经验
10+
这应该在VB中以几乎完全相同的方式完成。您可以在VB中使用默认实例以错误的方式执行操作,但您不应该这样做。
 
已加入
2020年3月20日
留言内容
65
编程经验
10+
嗨JM

谢谢您关于使用RadioButtons的建议,它比我以前的方法要精巧得多。我没有显示表格的问题,但是我可以将其关闭,如下所示。

C#:
        private void CmdSetupExchanges_CheckedChanged(object sender, EventArgs e)
        {
            switch (CmdSetupExchanges.Checked)
            {
                case true:
                    PicSetup.Visible = true;

                    Form frmSetup = new FrmSetupExchanges
                    {
                        TopLevel = false,
                        ControlBox = false,
                        Dock = DockStyle.Fill
                    };
                    PnlContainer.Controls.Add(frmSetup);
                    frmSetup.Show();
                    break;
                case false:
                    PicSetup.Visible = false;
                    Form frmSetupOpen = new FrmSetupExchanges();
                    frmSetupOpen.Close();
                    break;
                default:
                    break;
            }

        }

我也曾尝试清理面板,但再次表格保持打开状态,我无法弄清楚自己在做什么错。

再次感谢
AJ
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,566
地点
悉尼,澳大利亚
编程经验
10+
问题是您不是要关闭显示的表单,而是要关闭刚刚创建的新表单。如果我炸开气球并把它给了你,然后抓起一个新气球并炸掉它,然后在其中插了一根别针,您是否希望气球弹出?当然不是。那太神奇了。为什么,那么您希望这会在这里发生吗?如果创建并显示表单,然后创建一个新表单并关闭该表单,为什么还要关闭第一个表单?您需要能够访问之前创建的表单对象,以便可以将其关闭。正如您的代码所示,执行此操作的方法是从 控制项 的集合 控制板。另一种方法是只有一个 frmSetup 类级别的变量,而不是多个局部变量。可以从代码中的任何位置访问该字段。
 
已加入
2020年3月20日
留言内容
65
编程经验
10+
谢谢Jm

我只意识到自己的错误:重新初始化一种新表单,然后在发布后关闭该表单。如果我对您的理解正确,我应该在frmMain上声明我的表单(frmSetup)并使用该变量打开和关闭我的表单?我现在要尝试一下。我也会改变"switch" to "if"声明,我一直是案例盒的拥护者,但我同意,仅在两种情况下是不必要的。
 
已加入
2020年3月20日
留言内容
65
编程经验
10+
嗨Jm

我在这里取得了进展,但是创建了一个新问题。下面的代码可以正常工作,但是只有一次,如果我尝试再次打开表单,我会得到一个"无法访问已处置的对象" exception.

C#:
    public partial class FrmMain : Form
    {
        private Form frmSetup = new FrmSetupExchanges();

        public FrmMain()
        {;
            InitializeComponent();
        }
        
                private void CmdSetupExchanges_CheckedChanged(object sender, EventArgs e)
        {
            switch (CmdSetupExchanges.Checked)
            {
                case true:
                    PicSetup.Visible = true;
                    frmSetup.TopLevel = false;
                    frmSetup.ControlBox = false;
                    frmSetup.Dock = DockStyle.Fill;
                    PnlContainer.Controls.Add(frmSetup);
                    frmSetup.Show();
                    break; 
                case false:
                    PicSetup.Visible = false;
                    PnlContainer.Controls.Remove(frmSetup);
                    frmSetup.Close();
                    break;
                default:
                    break;
            }

        }

我想我理解为什么,当我声明它时,我正在初始化表单,因此当我尝试再次显示它时,该表单已被处置且未重新初始化。但是后来我尝试只声明表单并在显示表单时对其进行初始化,但随后我就得到了"未使用的局部变量" errors.

C#:
public Form frmSetup = null;

       private void CmdSetupExchanges_CheckedChanged(object sender, EventArgs e)
        {
            switch (CmdSetupExchanges.Checked)
            {
                case true:
                    Form frmSetup = new FrmSetupExchanges
                    {
                        TopLevel = false,
                        ControlBox = false,
                        Dock = DockStyle.Fill
                    };
                    PnlContainer.Controls.Add(frmSetup);
                    frmSetup.Show();
                    break; 
                case false:
                    PicSetup.Visible = false;
                    PnlContainer.Controls.Remove(frmSetup);
                    frmSetup.Close();
                    break;
                default:
                    break;
            }

        }

亚高,把我的头发拉到这里。
 
已加入
2020年3月20日
留言内容
65
编程经验
10+
对不起,Jm,我不明白,这种情况下的局部变量是"frmSetup"and i get the "unassigned variable"错误情况下的错误。我不能取代"frmSetup" with "frmsetupExchanges'在错误的情况下,我看不到我所缺少的。
请把我从痛苦中解救出来。 :)
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,566
地点
悉尼,澳大利亚
编程经验
10+
在这里,您要声明一个局部变量并为其分配新的表单:
C#:
case true:
    Form frmSetup = new FrmSetupExchanges
                        {
                            TopLevel = false,
                            ControlBox = false,
                            Dock = DockStyle.Fill
                        };
    PnlContainer.Controls.Add(frmSetup);
    frmSetup.Show();
    break;
整个问题是您没有将表单分配给局部变量,以便以后可以访问该表单并关闭它。您应该将表单分配给成员变量:
C#:
case true:
    frmSetup = new FrmSetupExchanges
                   {
                       TopLevel = false,
                       ControlBox = false,
                       Dock = DockStyle.Fill
                   };
    PnlContainer.Controls.Add(frmSetup);
    frmSetup.Show();
    break;
 
最佳 底部