怎么样才可以关闭主窗体,打开登录窗体?

我心依旧 2017-01-31 01:58:50
我这边有一个问题,主窗体是由登录窗体创建的,现在我要实现,切换用户的功能。就是我点一下“用户切换”的按钮,然后把主窗给关掉,打开登录窗体。但是现在我把主窗体关掉之后,打开的登录窗体也一块关掉了。怎么破解?
...全文
338 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
cpycpy000 2017-02-02
  • 打赏
  • 举报
回复
这个根本就不需要任何设计模式,因为就是两句话: ① 其实登录窗口才是真正的主窗体,因为它是你这整个程序的入口; ② 要实现切换用户,那只要保证你的“主窗体(登录窗口)”不被关闭,不管你打开的是哪个用户的操作界面,关掉之后都会回到这个登录窗口。
  • 打赏
  • 举报
回复
GOF 并不懂事件驱动的开发模式,所以他们 23 中设计模式中,80%都是冗余的,而描述中 90% 以上都是雷人的、不明确的。在 GOF 写设计模式那本书之前的许多年,不论是汇编编程、c语言编程、vb for dos 编程等等,许多工具方面都已经习惯了用地址表驱动、中断回调驱动等方式来解耦底层和高层系统之间的跨层依赖关系,甚至在一些编程语言中有简洁清晰地“事件机制”。GOF的设计模式这本书,如果他们有明确的事件概念,那么他们的书恐怕连十分之一的篇幅都没有,就足够了! 有些人在软件工程知识方面只是学习许多年前的 java 书的,所以学习了冗长拖沓的《设计模式》这本书。这个书有害,不是因为它写错了,而是因为它用了非常非常雷人的方式,不够清晰简明。
  • 打赏
  • 举报
回复
"是什么什么模式”这种判断,其实往往无助于直接聊当地进行 c# 编程设计。你可以看到网上的所谓的“设计模式”有多么脱离 .net 机制,反过来你也可以看到,我们是非常直截了当地、非常明白地来来介绍编程设计模式,而不用 GOF 那种雷人的说法来讲解设计模式。
传说之心 2017-02-02
  • 打赏
  • 举报
回复
其实就是观察者模式而已
wzyxs 2017-02-01
  • 打赏
  • 举报
回复
引用 7 楼 sp1234 的回复:
在另一个子 Thread 中重新 hang 主另外一个窗口,首先,它是改变了 UI 线程,这会在你的程序稍微复杂一点时(不仅仅有 this 还有更多的异步代码与之相关),立刻发现许多最初难以预料的 bug。传统的程序,UI 线程就一个,而这里变成了两个,动摇了。 另外,这个流程并没有回答后半段的需求,也就是“点一下用户切换按钮”之后的流程。实际上如果这时候再来一个
new Thread(() => Application.Run(new LoginForm())).Start();
的话,那么又增加了一倍的复杂性。此时你又在子窗体去多出来一个 UI 线程,并且这个子窗体又去创建“主窗体”,这本身就是在子窗体去依赖于主窗体。逻辑上就更乱了。 “主窗体永远不执行 Close”,这个原则保证不会有 UI 线程反复改变的问题,也只有单向依赖的逻辑关系,是最简单的模式。
你想多了,这样不过是变了几次ui线程(也就相当于重启了程序,毕竟原来的ui线程已经释放了),或同时有多个ui线程而已,而且线程间没有依赖,窗口用完就扔就可以(close)。 登录窗口通过new Thread(() => Application.Run(new Form())).Start();创建主窗口,随后释放登录窗口就可以了。 同理主窗口也可以用此方法创建登录窗口; 另外参数可以在new form(paras)时传递,例如登录信息等; 还有如果可以保证线程安全,可以设置线程ApartmentState属性为ApartmentState.STA,这样就可以在form2中执行form1.close()了。
  • 打赏
  • 举报
回复
在另一个子 Thread 中重新 hang 主另外一个窗口,首先,它是改变了 UI 线程,这会在你的程序稍微复杂一点时(不仅仅有 this 还有更多的异步代码与之相关),立刻发现许多最初难以预料的 bug。传统的程序,UI 线程就一个,而这里变成了两个,动摇了。 另外,这个流程并没有回答后半段的需求,也就是“点一下用户切换按钮”之后的流程。实际上如果这时候再来一个
new Thread(() => Application.Run(new LoginForm())).Start();
的话,那么又增加了一倍的复杂性。此时你又在子窗体去多出来一个 UI 线程,并且这个子窗体又去创建“主窗体”,这本身就是在子窗体去依赖于主窗体。逻辑上就更乱了。 “主窗体永远不执行 Close”,这个原则保证不会有 UI 线程反复改变的问题,也只有单向依赖的逻辑关系,是最简单的模式。
wzyxs 2017-01-31
  • 打赏
  • 举报
回复
楼上说的都对,不过其实有很简单的解决方法,只要不让两个窗口有依赖关系就可以了。 如果点击form1的button1要弹出form2并关闭form1,只要在button1的click里这样写就可以了: private void button1_Click(object sender, EventArgs e) { new Thread(() => Application.Run(new Form2())).Start(); this.Close(); }
mastzou1980 2017-01-31
  • 打赏
  • 举报
回复
帮你顶。。。。。。。。。。。。。。。。。
  • 打赏
  • 举报
回复
这里你要搞懂的技术知识是:事件驱动设计模式。 如果不搞懂这个,那么许多知识都白学了,你会用诡异的方式而不是正常的事件回调方式来编程。
  • 打赏
  • 举报
回复
Form1中定义一个 bool 字段
public bool CloseForLogin;

private void button1_Click(object sender, EventArgs e)
{
    this.CloseForLogin = true;
    this.Close();
}
  • 打赏
  • 举报
回复
对于窗体程序来说,“主窗体”其实就是你的登陆窗体。只不过你真的应用程序硬要把逻辑上的主窗体跟编程上的主窗体混为一谈,所以也就乱了。 应用程序的主窗体如果是 LoginForm,然后创建一个 Form1,可以这样写
private void button1_Click(object sender, EventArgs e)
{
    //判断是否登录成功,假设登录成功,继续执行以下功能
    var f = new Form1();
    f.FormClosed += (s, arg) =>
    {
        if (f.CloseForLogin)
            this.Show();
        else
            this.Close();
    };
    this.Hide();
    f.Show();
}
作为应用程序主窗体,这个登录窗体不能关闭(否则进程就关闭了),而是 Hide!它监听子窗口的关闭事件,然后判断子窗体到底是要重新登录呢?还是要关闭进程。 在 Form1中,你需要自定义一个负责让宿主能检查退出原因的 bool 字段:
private void button1_Click(object sender, EventArgs e)
{
    this.CloseForLogin = true;
    this.Close();
}
在关闭窗体之前,要设置好这个退出标志。
cpycpy000 2017-01-31
  • 打赏
  • 举报
回复
如果你的主窗体是由登录窗体创建的话, 那么逻辑就应该是: 登录窗体hidden() → 主窗体showdialog() → 主窗体close() → 登录窗体show() 注意全程 登录窗体不执行任何close()

110,545

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧