Пользовательский интерфейс не загружается при использовании в цикле Foreach - PullRequest
0 голосов
/ 10 января 2019

Я делаю программу, которую вы можете создать и загрузить в виде пакета с помощью CSV-файлов. Когда выбран файл CSV, он открывает другой пользовательский интерфейс с вопросом, ответом и изображением для карточки и продолжает цикл до тех пор, пока все карточки в пакете не пройдут, используя цикл 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;
        }

Это исправило проблему повторного зацикливания без нажатия кнопки для следующей карточки, но теперь он даже не открывает второй пользовательский интерфейс для нажатия следующей кнопки карточки.

Как бы это исправить? Любая помощь будет принята с благодарностью.

Код для цикла 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.question, record.answer и record.image, изменяется в зависимости от того, на какой строке находится цикл.

1 Ответ

0 голосов
/ 10 января 2019

Одна идея, которая приходит на ум, - хранить список записей вне метода, отслеживать следующую запись, которая должна быть прочитана, и изменять метод так, чтобы он просто читал следующую запись.

Затем, в вашем событии 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");
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...