在Foreach循环中使用UI时未加载UI

时间:2019-01-10 19:04:28

标签: c# winforms foreach

我正在制作一个程序,您可以使用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; }

然后创建private FileHelperEngine<FlashcardPack> engine = new FileHelperEngine<FlashcardPack>();的FileHelpers引擎的新实例,以读取csv文件,并且每当foreach循环循环record.question,record.answer和record.image时,其变化取决于循环的行数

1 个答案:

答案 0 :(得分:0)

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

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

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");
    }
}