【问题标题】:C# Form disappears without being told toC# Form 在没有被告知的情况下消失
【发布时间】:2018-07-30 17:52:04
【问题描述】:

所以我有一个表单,它创建另一个表单并使用Form.ShowDialog() 调用它,但是在运行过程中的某个时间点,新表单消失了。我可以说它仍在运行,因为我设置了一个计时器,完成后会显示一个消息框。消息框在分配的时间后仍然显示,但表单不再可见。

要调用我使用此代码的表单:

Player currentUser = new Player(); //Player is a class I've created

private void Game(int PlayerCount)
{
    Current.Hide();
    for (int i = 0; i < PlayerCount; i++)
    {
        currentUser = GloVar.CurrentPlayers[i];
        CashBuilder cb = new CashBuilder(currentUser);
        cb.ShowDialog();
    }
 }

“cb”表单显示,我可以与它进行交互,直到我按下一个按钮。 表单中有一个方法可以检查答案(有四个按钮,一个是正确的)是否正确。

private void IsCorrect(int i)
{
    if (CorrectAnswer == i) 
    {
        lblFeedback.Text = "Correct."; 
        AnsweredCorrectly++; //add to the answered correctly list
        Timer2.Start(); //this timer is used to increment a value of money, it does not call on anything else and lasts 1.5 seconds.
    }
    else
    {
        lblFeedback.Text = correctAnswer;
    }
    QuestionsAnswered++; //add to questions answered
    Generate_Question(); //bring a new question
}

如果答案在正确和错误之间交替出现,表格 SEEMS(我无法 100% 澄清)保持可见。 但是,如果我回答正确然后正确(或不正确和不正确),表格就会消失。

我有一个关闭表单的方法,但是直到计时器到时才被触及。

我已经搜索了大约一个星期来寻找解决方案,尝试了多个线程(让线程工作但仍然遇到这个问题),我想不出别的了。


编辑

这是 CashBuilder 的完整源代码

public partial class CashBuilder : Form
{
    public static CashBuilder current;
    private static int QuestionID; //Identifies the loctaion of the question
    private static int CorrectAnswer; //holds the place of the correct answer
    private static int CountDown = 60; //hold a count of 60, one foe earch second. This adds to a minute.
    private static int QuestionsAnswered = 0; //how many questions have been answered
    private static int AnsweredCorrectly = 0; //out of those how many correctly
    private static int CashWon = 0; //chash won, £1000 per correct answer
    private static int Wait = 10; //holds ten ticks for the second timer
    private static Timer Timer1; //One minute, used to time the Cash Builder round
    private static Timer Timer2; //One fifth of a second, used for adding £1000 to cash wont every correct answer. Looks like a gameshow
    private static Player User;



    public CashBuilder(Player user)
    {
        InitializeComponent();
        current = this;
        User = user;
        pctAvatar.Image = Image.FromFile(GloVar.Avatar(User.ID));
        Generate_Question();
        btnCash.Text = "£0000"; //sets initial Cash Won lable to nothing
        Timer1 = new Timer(); //Creates a new timer
        Timer1.Tick += new EventHandler(timer_Tick);
        Timer1.Interval = 1000; //1 second
        Timer1.Start(); //Starts timer, this is the begining of the round
        btnTime.Text = "Time Left: " + CountDown.ToString();
        Timer2 = new Timer();
        Timer2.Tick += new EventHandler(Timer2_Tick);
        Timer2.Interval = 20; //0.02 seconds
    }

    void timer_Tick(object sender, EventArgs e)
    {
        CountDown--; //takes one away from time left
        btnTime.Text = "Time Left: " + CountDown.ToString(); //shows the user
        if (CountDown == 0) //if theres no time left
        {
            Timer1.Stop(); //stop timer
            Enough();
        }
    }

    private void Timer2_Tick(object sender, EventArgs e)
    {
        Wait--;
        CashWon += 100; //adds 100 to the cash won. Ticks ten times therefore end will be +1000
        btnCash.Text = "£" + CashWon.ToString(); //shows user
        if (Wait == 0)
        {
            Timer2.Stop();
            Wait = 10; //resets the tick count for a later question
        }
    }

    private void Generate_Question()
    {
        Random rnd = new Random();  //used to generate a random value (only integers in this case) within parameters given

        do
        {
            QuestionID = rnd.Next(82); //there are only 82 questions, references as a zero-index. Cannot generate 82.
        } while (GloVar.QuestionsAsked.Contains(QuestionID)); //continue loop if question has already been asked
        GloVar.QuestionsAsked.Add(QuestionID); //if question hasnt been asked, add it to the list of asked questions
        btnQuestion.Text = GloVar.Questions[(QuestionID * 6) + 1]; //show the question on the form


        List<int> AnswerPlacement = new List<int>(); //used to see what answers have already been placed
        int[] Answers = new int[4]; //holds placevalues for the answers
        for (int i = 0; i < 4; i++)
        {
            do
            {
                Answers[i] = rnd.Next(4); //generates random placevalue
            } while (AnswerPlacement.Contains(Answers[i])); //while the placevalue entered is already used
            AnswerPlacement.Add(Answers[i]); //show the placevalue has been used
            if (Answers[i] == 0)
            {
                CorrectAnswer = i;
            }
        }

        btnAns1.Text = GloVar.Questions[(QuestionID * 6) + Answers[0] + 2]; //giving buttons their answers
        btnAns2.Text = GloVar.Questions[(QuestionID * 6) + Answers[1] + 2];
        btnAns3.Text = GloVar.Questions[(QuestionID * 6) + Answers[2] + 2];
        btnAns4.Text = GloVar.Questions[(QuestionID * 6) + Answers[3] + 2];

        AnswerPlacement.Clear();
        lblFeedback.Text = "";
    }

    private void btnAns1_Click(object sender, EventArgs e)
    {
        IsCorrect(0);
    }

    private void btnAns2_Click(object sender, EventArgs e)
    {
        IsCorrect(1);
    }

    private void btnAns3_Click(object sender, EventArgs e)
    {
        IsCorrect(2);
    }

    private void btnAns4_Click(object sender, EventArgs e)
    {
        IsCorrect(3);
    }

    private void btnPass_Click(object sender, EventArgs e)
    {
        Generate_Question();
        QuestionsAnswered++;
    }

    private void IsCorrect(int i)
    {
        if (CorrectAnswer == i) //if the place of the button value given and the correct answer are the same
        {
            lblFeedback.Text = "Correct."; //show the user their awesomeness
            AnsweredCorrectly++; //add to the answered correctly list
            Timer2.Start(); //this timer adds the newly gained £1000
        }
        else
        {
            lblFeedback.Text = Convert.ToString(SSDTheChase.GloVar.Questions[(QuestionID * 6) + 2]); //show their failure
        }
        QuestionsAnswered++; //add to questions answered
        Generate_Question(); //bring a new question
    }

    private void Enough()
    {
        btnAns1.Text = ""; //set all buttons and lables used for a question equal to zero
        btnAns2.Text = "";
        btnAns3.Text = "";
        btnAns4.Text = "";
        btnQuestion.Text = "";
        CountDown = 60; //resetting time
        MessageBox.Show("Time's up." + Environment.NewLine + QuestionsAnswered + " Questions Answered." + Environment.NewLine + AnsweredCorrectly + " Answered Correctly.");
        User.CashGame = CashWon; //setting the users cash won this game.

        current.Close(); //close the form.
    }
}

【问题讨论】:

  • 还有Generate_Question();中的表格关闭吗?
  • 为 FormClosing 事件添加事件处理程序并在其上设置断点。堆栈跟踪应该向您展示它决定关闭的原因。顺便说一句,Current.Hide() 是一个候选者,但您发布的代码没人可以测试,我们确实避免尝试猜测它。
  • @MarkBenovsky 方法 Generate_Question() 现在包含在课程代码中
  • @HansPassant 表单没有关闭,它似乎失去了可见性。抱歉代码,第一次在这里发布。
  • 您可能想用static current 实现单例?以其他方式创建单例,在网上搜索它。如果没有,只需删除它,您的类继承Form,因此您可以在没有任何引用的情况下调用Close(),如果您的表单失去可见性,请尝试调试您的代码并找出隐藏的代码部分

标签: c# winforms .net-3.0


【解决方案1】:

部分答案,因为我无法发表评论,但您调用 cb.ShowDialog() 而不是 cb.Show() 是否有原因?您描述的行为听起来像一个消息框(请参阅备注部分中的here

我的第一个想法是,当您连续给出两个正确(或不正确)的答案时,它就像一个消息框并返回 cb.DialogResult.Yes(或 .No)。消息框不会像表单一样关闭,它们会隐藏起来,直到调用 .Dispose()。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-21
    • 2022-08-12
    相关资源
    最近更新 更多