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

t1rydlwq  于 6个月前  发布在  其他
关注(0)|答案(2)|浏览(73)

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

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.IO;

namespace Midnight_Serverpanel
{
    public partial class login : Form
    {
        public login()
        {
            InitializeComponent();
        }
    
        private void button1_Click_1(object sender, EventArgs e)
        {
            OpenStartForm();
        }

        private bool IsUserLoggedIn()
        {
            string tokenFilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Google.Apis.Auth", "Google.Apis.Auth.OAuth2.Responses.TokenResponse-user");
    
            try
            {
                if (File.Exists(tokenFilePath))
                {
                    // Überprüfen, ob die Datei einen gültigen Inhalt hat
                    string tokenContent = File.ReadAllText(tokenFilePath);

                    if (!string.IsNullOrEmpty(tokenContent))
                    {
                        return true;
                    }
                }
            }
            catch (Exception ex)
            {
                // Hier könntest du die Fehlermeldung protokollieren oder debuggen
                MessageBox.Show("Fehler beim Überprüfen des Tokens: " + ex.Message);
            }
    
            return false;
        }
    
        private void login_Load(object sender, EventArgs e)
        {
            if (IsUserLoggedIn())
            {
                Program.UserLoggedIn = true;
                OpenStartForm();
            }
        }

        private void OpenStartForm()
        {
            try
            {
                Start sistema = new Start();
                sistema.Show();
                this.Hide();  // Close the current form
            }
            catch (Exception ex)
            {
                MessageBox.Show("Fehler beim Öffnen des Startformulars: " + ex.Message);
            }
        }
    }
}

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

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.Win32;
using Renci.SshNet;
using Renci.SshNet.Common;
using System.Runtime.InteropServices;
using System.IO;
using System.Threading;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Util;
//google

namespace Midnight_Serverpanel
{
    public partial class Start : Form
    {
        Liveserver u1;
        Devserver u2;
        Compilen u3;
    
        public Start()
        {
            u1 = new Liveserver();
            u2 = new Devserver();
            u3 = new Compilen();
            InitializeComponent();
        }

        public class MultiTextWriter : TextWriter
        {
            private IEnumerable<TextWriter> writers;

            public MultiTextWriter(IEnumerable<TextWriter> writers)
            {
                this.writers = writers.ToList();
            }

            public MultiTextWriter(params TextWriter[] writers)
            {
                this.writers = writers;
            }
    
            public override void Write(char value)
            {
                foreach (var writer in writers)
                    writer.Write(value);
            }
    
            public override void Write(string value)
            {
                foreach (var writer in writers)
                    writer.Write(value);
            }
    
            public override void Flush()
            {
                foreach (var writer in writers)
                    writer.Flush();
            }
    
            public override void Close()
            {
                foreach (var writer in writers)
                    writer.Close();
            }
    
            public override Encoding Encoding
            {
                get { return Encoding.ASCII; }
            }
        }

        public class ControlWriter : TextWriter
        {
            private Control textbox;

            public ControlWriter(Control textbox)
            {
                this.textbox = textbox;
            }
    
            public override void Write(char value)
            {
                textbox.Text += value;
            }
    
            public override void Write(string value)
            {
                textbox.Text += value;
            }
    
            public override Encoding Encoding
            {
                get { return Encoding.ASCII; }
            }
        }
    
        private void toolStripMenuItem1_Click(object sender, EventArgs e)
        {
            this.panel1.Controls.Clear();
            u2.Hide();
            u3.Hide();
            u1.Show();
            u1.Dock = DockStyle.Fill;
            panel1.Controls.Add(u1);
        }

        private void toolStripMenuItem2_Click(object sender, EventArgs e)
        {
            this.panel1.Controls.Clear();
            u1.Hide();
            u3.Hide();
            u2.Show();
            u2.Dock = DockStyle.Fill;
            panel1.Controls.Add(u2);
        }

        private void toolStripMenuItem3_Click(object sender, EventArgs e)
        {
            this.panel1.Controls.Clear();
            u1.Hide();
            u2.Hide();
            u3.Show();
            u3.Dock = DockStyle.Fill;
            panel1.Controls.Add(u3);
        }
    
        private void toolStripMenuItem1_Click_1(object sender, EventArgs e)
        {
            this.panel1.Controls.Clear();
            u2.Hide();
            u3.Hide();
            u1.Show();
            u1.Dock = DockStyle.Fill;
            panel1.Controls.Add(u1);
        }
    }
}


我的Program.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Midnight_Serverpanel
{
    internal static class Program
    {
        public static bool OpenDetailFormOnClose { get; set; }
        public static bool UserLoggedIn { get; set; }  // Add a property to track user login status
        /// <summary>
        /// Der Haupteinstiegspunkt für die Anwendung.
        /// </summary>
        [STAThread]
        static void Main()
        {
             Application.EnableVisualStyles();
             Application.SetCompatibleTextRenderingDefault(false);
             Application.Run(new login());
        }

        private static bool IsUserLoggedIn()
        {
            string tokenFilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Google.Apis.Auth", "Google.Apis.Auth.OAuth2.Responses.TokenResponse-user");
    
            try
            {
                if (File.Exists(tokenFilePath))
                {
                    // Überprüfen, ob die Datei einen gültigen Inhalt hat
                    string tokenContent = File.ReadAllText(tokenFilePath);

                    if (!string.IsNullOrEmpty(tokenContent))
                    {
                        return true;
                    }
                }
            }
            catch (Exception ex)
            {
                // Hier könntest du die Fehlermeldung protokollieren oder debuggen
                MessageBox.Show("Fehler beim Überprüfen des Tokens: " + ex.Message);
            }
    
            return false;
        }
    }
}


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

qnzebej0

qnzebej01#

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

class LoginService {
    public bool IsUserLoggedIn(){...}
    public void SetToken(token){...}
    public string GetToken(){...}
}

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

hi3rlvi2

hi3rlvi22#

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

public partial class LoginForm : Form
{
    // some stuff...
    private void MethodAfterUserLogIn()
    {
        this.Hide();
        var startForm = new StartForm();
        startForm.Closing += delegate { this.Close(); };
        startForm.Show();
    }
}

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

internal class AuthHelper
{
    private static bool _isUserLoggedIn;

    internal static bool IsUserLoggedIn()
    {
        // User login status check logic...
        return _isUserLoggedIn; // result of login status check
    }
    internal static void LogIn(string username, string password)
    {
        // Log in logic...
        _isUserLoggedIn = true; // result of log in actions
    }
    internal static void LogOut(string username, string password)
    {
        // Log out logic...
        _isUserLoggedIn = false; // result of log our actions
    }
    internal static void SignUp(string username, string password)
    {
        // Sign up logic...
        // return? result of sign up actions
    }
}


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

public static class Program
{
    [STAThread]
    public static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        if (!AuthHelper.IsUserLoggedIn())
           Application.Run(new LoginForm());
        if (AuthHelper.IsUserLoggedIn())
            Application.Run(new StartForm());
        // twice check because from here we don't know, 
        // was user logged in Login form or just cancelled (closed) it
    }
}


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

public partial class LoginForm : Form
{
    public LoginForm() => InitializeComponent();

    // Imagine that this is "Authorize"/"Log in" button
    private void Authorize_Click(object sender, EventArgs e)
    {
        AuthHelper.LogIn(tbUsername.Text, tbPassword.Text);
        // if (for any reason not logged in)
        // {
        //     MessageBox.Show(explain why)
        //     return; not Close here to allow user take another log in attempt
        // }

        // Means login action was successful and we can close form
        this.Close();
    }
    // Imagine that this is "Register"/"Sign up" button
    private void Register_Click(object sender, EventArgs e)
    {
        AuthHelper.SignUp(tbUsername.Text, tbPassword.Text);
        // After signing up user probably supposed to log in?
    }
}


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

相关问题