在Foreach循环中使用时不会加载UI

问题描述 投票:-2回答:1

我正在创建一个程序,您可以使用csv文件创建并加载到闪存卡包中。当选择csv文件时,它会打开其他UI,其中包含闪存卡的问题,答案和图像,并将继续循环,直到包中的所有闪存卡都使用foreach循环完成。

然而,foreach循环将继续循环而无需用户按下一个按钮。为了解决这个问题我做了:

                while (Continue() == false) { } //this is at the end of the foreach loop

                }
        }

        private bool Continue()
        {
            if (btn_NextFlashcard_WasClicked) return true;
            Application.DoEvents();
            Thread.Sleep(250);
            Application.DoEvents();
            return false;
        }

        private bool btn_NextFlashcard_WasClicked;

        private void btn_NextFlashcard_Click(object sender, EventArgs e)
        {
            btn_NextFlashcard_WasClicked = true;
        }

这解决了它再次循环的问题,没有按下下一张闪存卡的按钮,但现在它甚至没有打开第二个UI,让我按下一个闪卡按钮。

我该如何解决这个问题?任何帮助将不胜感激。

foreach循环代码:

public void ReadFlashcardPack(string file)
        {
            var records = engine.ReadFile(file);

                foreach (var record in records)
                {

                    Console.WriteLine("New foreach loop");

                    lblQuestion.Text = record.question;
                    lblAnswer.Text = record.answer;

                    lblAnswer.Visible = false;
                    btn_NextFlashcard_WasClicked = false;

                    //check if there is an image
                    if (record.image == "FALSE")
                    {
                        Image.Hide();
                    }
                    else
                    {
                        Image.Show();
                        Image.Image = Properties.Resources.test_image;
                    }

                    while (Continue() == false) { }

                }
        }

记录也来自一个类:[DelimitedRecord(",")] public class FlashcardPack { public string question; public string answer; public string image; }

然后一个新的FileHelpers引擎实例使private FileHelperEngine<FlashcardPack> engine = new FileHelperEngine<FlashcardPack>();读取csv文件,每次foreach循环循环记录时,record.answer和record.image会根据循环所在的行而改变。

c# winforms foreach
1个回答
0
投票

想到的一个想法是在方法之外存储记录列表,跟踪应该读取的下一条记录,并修改方法以只读取下一条记录。

然后,在您的单击事件中,您可以再次调用该方法,直到读取所有记录。

private string filePath = @"f:\private\temp\temp.csv"; // Use your file path here
private List<FlashcardPack> records;
private int nextRecord;

public void ReadNextRecord()
{
    if (records == null)
    {
        records = engine.ReadFile(filePath).ToList();
        nextRecord = 0;
    }
    else if (nextRecord >= records.Count)
    {
        // Do something when all records have been read
        nextRecord = 0; 
    }

    // Get next record and increment our variable
    var record = records[nextRecord++];

    lblQuestion.Text = record.question;
    lblAnswer.Text = record.answer;

    lblAnswer.Visible = false;
    btn_NextFlashcard_WasClicked = false;

    //check if there is an image
    if (record.image == "FALSE")
    {
        Image.Hide();
    }
    else
    {
        Image.Show();
        Image.Image = Properties.Resources.test_image;
    }
}

private void btn_NextFlashcard_Click(object sender, EventArgs e)
{
    ReadNextRecord();
}

这是一个使用上述概念的工作示例,它可以帮助您使代码正常工作,因为我无法看到您的整个项目:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private List<Flashcard> flashcards;
    private int nextRecord;

    // Use a valid path on your system here (the file doesn't need to exist)
    private const string FilePath = @"f:\public\temp\temp.csv";

    private void LoadFlashcards()
    {
        flashcards = Engine.ReadFile(FilePath);
        nextRecord = 0;
    }

    public void DisplayNextFlashcard()
    {
        if (flashcards == null)
        {
            LoadFlashcards();
        }
        else if (nextRecord >= flashcards.Count)
        {
            // Do something when all records have been read
            nextRecord = 0;
        }

        var flashcard = flashcards[nextRecord++];

        lblQuestion.Text = flashcard.Question;
        lblAnswer.Visible = false;
        lblAnswer.Text = flashcard.Answer;

        Image.Visible = flashcard.Image;
        Image.Image = Properties.Resources.FlashcardImage;
    }

    private void btn_NextFlashcard_Click(object sender, EventArgs e)
    {
        DisplayNextFlashcard();
    }
}

class Flashcard
{
    public string Question { get; set; }
    public string Answer { get; set; }
    public bool Image { get; set; }

    public static Flashcard Parse(string csvLine)
    {
        if (csvLine == null) throw new ArgumentNullException(nameof(csvLine));
        var parts = csvLine.Split(',').Select(item => item.Trim()).ToList();
        if (parts.Count != 3) throw new FormatException(
            "csvLine does not contain 3 comma-separated items.");

        return new Flashcard
        {
            Question = parts[0],
            Answer = parts[1],
            Image = !parts[2].Equals("FALSE", StringComparison.OrdinalIgnoreCase)
        };
    }
}

class Engine
{
    public static List<Flashcard> ReadFile(string filePath)
    {
        if (filePath == null) throw new ArgumentNullException(nameof(filePath));
        if (!File.Exists(filePath)) CreateFile(filePath);
        return File.ReadAllLines(filePath).Select(Flashcard.Parse).ToList();
    }

    private static void CreateFile(string filePath)
    {
        File.CreateText(filePath).Close();
        File.WriteAllText(filePath, 
            "What is more useful when it is broken?, An egg, TRUE\n" +
            "What belongs to you but other people use it more?, Your name, FALSE\n" +
            "I have three eyes all in a row. When the red one opens " +
            "no one can go. What am I?, A traffic light, TRUE");
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.