关于打开和关闭其他窗体的基本C# WinForms问题

t1rydlwq  于 2023-11-21  发布在  其他
关注(0)|答案(2)|浏览(253)

我在login.cs中有一个代码:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using System.Windows.Forms;
  10. using System.Data.SqlClient;
  11. using System.IO;
  12. namespace Midnight_Serverpanel
  13. {
  14. public partial class login : Form
  15. {
  16. public login()
  17. {
  18. InitializeComponent();
  19. }
  20. private void button1_Click_1(object sender, EventArgs e)
  21. {
  22. OpenStartForm();
  23. }
  24. private bool IsUserLoggedIn()
  25. {
  26. string tokenFilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Google.Apis.Auth", "Google.Apis.Auth.OAuth2.Responses.TokenResponse-user");
  27. try
  28. {
  29. if (File.Exists(tokenFilePath))
  30. {
  31. // Überprüfen, ob die Datei einen gültigen Inhalt hat
  32. string tokenContent = File.ReadAllText(tokenFilePath);
  33. if (!string.IsNullOrEmpty(tokenContent))
  34. {
  35. return true;
  36. }
  37. }
  38. }
  39. catch (Exception ex)
  40. {
  41. // Hier könntest du die Fehlermeldung protokollieren oder debuggen
  42. MessageBox.Show("Fehler beim Überprüfen des Tokens: " + ex.Message);
  43. }
  44. return false;
  45. }
  46. private void login_Load(object sender, EventArgs e)
  47. {
  48. if (IsUserLoggedIn())
  49. {
  50. Program.UserLoggedIn = true;
  51. OpenStartForm();
  52. }
  53. }
  54. private void OpenStartForm()
  55. {
  56. try
  57. {
  58. Start sistema = new Start();
  59. sistema.Show();
  60. this.Hide(); // Close the current form
  61. }
  62. catch (Exception ex)
  63. {
  64. MessageBox.Show("Fehler beim Öffnen des Startformulars: " + ex.Message);
  65. }
  66. }
  67. }
  68. }

字符串
我所希望的是,当一个usertoken被加载时,login.cs将被跳过,start.cs将被立即打开。但我所得到的是,这两个窗口都被打开,我不想看到那个带有“用谷歌登录”按钮的窗口。
我的Start.cs

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using System.Windows.Forms;
  10. using Microsoft.Win32;
  11. using Renci.SshNet;
  12. using Renci.SshNet.Common;
  13. using System.Runtime.InteropServices;
  14. using System.IO;
  15. using System.Threading;
  16. using Google.Apis.Auth.OAuth2;
  17. using Google.Apis.Util;
  18. //google
  19. namespace Midnight_Serverpanel
  20. {
  21. public partial class Start : Form
  22. {
  23. Liveserver u1;
  24. Devserver u2;
  25. Compilen u3;
  26. public Start()
  27. {
  28. u1 = new Liveserver();
  29. u2 = new Devserver();
  30. u3 = new Compilen();
  31. InitializeComponent();
  32. }
  33. public class MultiTextWriter : TextWriter
  34. {
  35. private IEnumerable<TextWriter> writers;
  36. public MultiTextWriter(IEnumerable<TextWriter> writers)
  37. {
  38. this.writers = writers.ToList();
  39. }
  40. public MultiTextWriter(params TextWriter[] writers)
  41. {
  42. this.writers = writers;
  43. }
  44. public override void Write(char value)
  45. {
  46. foreach (var writer in writers)
  47. writer.Write(value);
  48. }
  49. public override void Write(string value)
  50. {
  51. foreach (var writer in writers)
  52. writer.Write(value);
  53. }
  54. public override void Flush()
  55. {
  56. foreach (var writer in writers)
  57. writer.Flush();
  58. }
  59. public override void Close()
  60. {
  61. foreach (var writer in writers)
  62. writer.Close();
  63. }
  64. public override Encoding Encoding
  65. {
  66. get { return Encoding.ASCII; }
  67. }
  68. }
  69. public class ControlWriter : TextWriter
  70. {
  71. private Control textbox;
  72. public ControlWriter(Control textbox)
  73. {
  74. this.textbox = textbox;
  75. }
  76. public override void Write(char value)
  77. {
  78. textbox.Text += value;
  79. }
  80. public override void Write(string value)
  81. {
  82. textbox.Text += value;
  83. }
  84. public override Encoding Encoding
  85. {
  86. get { return Encoding.ASCII; }
  87. }
  88. }
  89. private void toolStripMenuItem1_Click(object sender, EventArgs e)
  90. {
  91. this.panel1.Controls.Clear();
  92. u2.Hide();
  93. u3.Hide();
  94. u1.Show();
  95. u1.Dock = DockStyle.Fill;
  96. panel1.Controls.Add(u1);
  97. }
  98. private void toolStripMenuItem2_Click(object sender, EventArgs e)
  99. {
  100. this.panel1.Controls.Clear();
  101. u1.Hide();
  102. u3.Hide();
  103. u2.Show();
  104. u2.Dock = DockStyle.Fill;
  105. panel1.Controls.Add(u2);
  106. }
  107. private void toolStripMenuItem3_Click(object sender, EventArgs e)
  108. {
  109. this.panel1.Controls.Clear();
  110. u1.Hide();
  111. u2.Hide();
  112. u3.Show();
  113. u3.Dock = DockStyle.Fill;
  114. panel1.Controls.Add(u3);
  115. }
  116. private void toolStripMenuItem1_Click_1(object sender, EventArgs e)
  117. {
  118. this.panel1.Controls.Clear();
  119. u2.Hide();
  120. u3.Hide();
  121. u1.Show();
  122. u1.Dock = DockStyle.Fill;
  123. panel1.Controls.Add(u1);
  124. }
  125. }
  126. }


我的Program.cs

  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Runtime.CompilerServices;
  6. using System.Threading.Tasks;
  7. using System.Windows.Forms;
  8. namespace Midnight_Serverpanel
  9. {
  10. internal static class Program
  11. {
  12. public static bool OpenDetailFormOnClose { get; set; }
  13. public static bool UserLoggedIn { get; set; } // Add a property to track user login status
  14. /// <summary>
  15. /// Der Haupteinstiegspunkt für die Anwendung.
  16. /// </summary>
  17. [STAThread]
  18. static void Main()
  19. {
  20. Application.EnableVisualStyles();
  21. Application.SetCompatibleTextRenderingDefault(false);
  22. Application.Run(new login());
  23. }
  24. private static bool IsUserLoggedIn()
  25. {
  26. string tokenFilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Google.Apis.Auth", "Google.Apis.Auth.OAuth2.Responses.TokenResponse-user");
  27. try
  28. {
  29. if (File.Exists(tokenFilePath))
  30. {
  31. // Überprüfen, ob die Datei einen gültigen Inhalt hat
  32. string tokenContent = File.ReadAllText(tokenFilePath);
  33. if (!string.IsNullOrEmpty(tokenContent))
  34. {
  35. return true;
  36. }
  37. }
  38. }
  39. catch (Exception ex)
  40. {
  41. // Hier könntest du die Fehlermeldung protokollieren oder debuggen
  42. MessageBox.Show("Fehler beim Überprüfen des Tokens: " + ex.Message);
  43. }
  44. return false;
  45. }
  46. }
  47. }


我真的很感激帮助,因为这是我写的第一个应用程序。
我喜欢一些帮助和建议。

qnzebej0

qnzebej01#

在开始你的应用程序Application.Run(new login());之前,你可以决定下一步的策略。首先,你必须把你的身份验证逻辑移动到单独的类中,并教它存储令牌。结果你会得到这样的东西

  1. class LoginService {
  2. public bool IsUserLoggedIn(){...}
  3. public void SetToken(token){...}
  4. public string GetToken(){...}
  5. }

字符串
让我们来决定哪个表单将成为你的应用程序的主表单,我认为,它可以是StartForm,用Application.Run(startForm)运行它;
接下来,在StartForm中创建服务示例,或者您可以在Program.cs中创建并使用构造函数传递给StartForm。在显示StartForm之前,请检查service.IsuserLoggedIn();
如果没有,打开LoginForm作为一个对话框var result = loginForm.ShowDialog();,在登录表单中确保您设置了这个。在关闭表单之前,如果您的授权成功,请设置DialogResult。好的,如果没有-设置取消。
在StartupForm中检查result变量,如果它是Ok,尝试从服务读取令牌。接下来,如果你有令牌,你可以开始工作。

hi3rlvi2

hi3rlvi22#

如果一个表单打开了其他的表单,那么它就不能被关闭。至少在这个表单打开之前,其他的表单会被关闭。
但是你可以在显示开始表单后隐藏你的登录表单,通过使用here建议的解决方案:

  1. public partial class LoginForm : Form
  2. {
  3. // some stuff...
  4. private void MethodAfterUserLogIn()
  5. {
  6. this.Hide();
  7. var startForm = new StartForm();
  8. startForm.Closing += delegate { this.Close(); };
  9. startForm.Show();
  10. }
  11. }

字符串
另一种方法可能有助于避免登录表单和开始表单之间的依赖性,并基于@GotStu建议-分离逻辑和责任。
登录表单应该做什么?允许用户输入用户名/密码。允许按下“登录”或“注册”按钮。表单本身应该检查用户登录状态吗?我认为不是。我认为,检查用户登录状态的责任应该属于类,它包含整体的授权相关逻辑。
例如,假设某个AuthHelper类带有一些相关的方法(非常原始):

  1. internal class AuthHelper
  2. {
  3. private static bool _isUserLoggedIn;
  4. internal static bool IsUserLoggedIn()
  5. {
  6. // User login status check logic...
  7. return _isUserLoggedIn; // result of login status check
  8. }
  9. internal static void LogIn(string username, string password)
  10. {
  11. // Log in logic...
  12. _isUserLoggedIn = true; // result of log in actions
  13. }
  14. internal static void LogOut(string username, string password)
  15. {
  16. // Log out logic...
  17. _isUserLoggedIn = false; // result of log our actions
  18. }
  19. internal static void SignUp(string username, string password)
  20. {
  21. // Sign up logic...
  22. // return? result of sign up actions
  23. }
  24. }


这里你可以看到封装的(隔离的,分离的)逻辑,只与用户身份验证相关。这个类不负责任何事情,除了用户身份验证,不依赖于登录表单或任何其他表单。如何使用它?
在你的例子中,你有一个简单的条件:“如果用户登录,那么显示开始表单,否则在” 之前显示登录表单。你可以直接将这个条件转移到Program.cs中。但是有两种方法:

  1. public static class Program
  2. {
  3. [STAThread]
  4. public static void Main()
  5. {
  6. Application.EnableVisualStyles();
  7. Application.SetCompatibleTextRenderingDefault(false);
  8. if (!AuthHelper.IsUserLoggedIn())
  9. Application.Run(new LoginForm());
  10. if (AuthHelper.IsUserLoggedIn())
  11. Application.Run(new StartForm());
  12. // twice check because from here we don't know,
  13. // was user logged in Login form or just cancelled (closed) it
  14. }
  15. }


例如,在登录表单中,我们执行登录/注册操作。而不是打开启动表单(成功授权后),我们关闭登录表单以允许应用程序现在运行另一个(启动)表单作为主表单:

  1. public partial class LoginForm : Form
  2. {
  3. public LoginForm() => InitializeComponent();
  4. // Imagine that this is "Authorize"/"Log in" button
  5. private void Authorize_Click(object sender, EventArgs e)
  6. {
  7. AuthHelper.LogIn(tbUsername.Text, tbPassword.Text);
  8. // if (for any reason not logged in)
  9. // {
  10. // MessageBox.Show(explain why)
  11. // return; not Close here to allow user take another log in attempt
  12. // }
  13. // Means login action was successful and we can close form
  14. this.Close();
  15. }
  16. // Imagine that this is "Register"/"Sign up" button
  17. private void Register_Click(object sender, EventArgs e)
  18. {
  19. AuthHelper.SignUp(tbUsername.Text, tbPassword.Text);
  20. // After signing up user probably supposed to log in?
  21. }
  22. }


与Program.cs一样,LoginForm.cs使用一些AuthHelper,只是将数据(用户名/密码)传递给它,但不对它们执行任何操作,因为这不是表单的责任。
启动表单,与登录表单相同,应该包含一些Log out调用,也利用负责该操作的AuthHelper类。注销后,启动表单应该关闭,应用程序应该返回到登录表单。但我委托repossibility来实现这一点给你)

展开查看全部

相关问题