P-Finny
P-Finny

Reputation: 261

Wait for button press in foreach

I have a WPF application that needs to show the user the name of an object in an XML file, wait for them to read it, then allow them to press a Continue button and see the next one.

I've simplified the code below, but need a way to wait for the button press.

private void Waitforpress()
{ 
    XDocument puppies = XDocument.Load(@"C:\puppies.xml");

    foreach (var item in puppies.Descendants("Row")
    {
        PuppyName = item.Element("puppyName").Value;

        // Call Print PuppyName function

        // WAIT HERE FOR BUTTON PRESS BEFORE GOING TO NEXT PUPPY NAME
    }        
}

Upvotes: 0

Views: 1157

Answers (2)

Servy
Servy

Reputation: 203802

You can use the following method to create a Task that will be completed when the button is clicked:

public static Task WhenClicked(this Button button)
{
    var tcs = new TaskCompletionSource<bool>();
    RoutedEventHandler handler = null;
    handler = (s, e) =>
    {
        tcs.TrySetResult(true);
        button.Click -= handler;
    };
    button.Click += handler;
    return tcs.Task;
}

You can then await that task so that your method will continue executing after the button is clicked:

private async Task Waitforpress()
{ 
    XDocument puppies = XDocument.Load(@"C:\puppies.xml");

    foreach (var item in puppies.Descendants("Row")
    {
        PuppyName = item.Element("puppyName").Value;

        // Call Print PuppyName function

        await button.WhenClicked();
    }        
}

Note that you probably want to be doing the file IO asynchronously, not synchronously, so as to not block the UI thread.

Upvotes: 1

Abe
Abe

Reputation: 274

You should not really load the file inside the button like that, I would suggest you to create a procedure that reads the file into a queue and, when the user press the button, you read the next queued item and show it to the user, such as:

    Queue<XElement> puppiesQueue = new Queue<XElement>();

    void LoadPuppies()
    {
        XDocument puppies = XDocument.Load(@"C:\puppies.xml");
        foreach (XElement puppie in puppies.Descendants("Row"))
            puppiesQueue.Enqueue(puppie);
    }

    void Button_Click()
    {
        //Each time you click the button, it will return you the next puppie in the queue.
        PuppyName = puppiesQueue.Dequeue().Element("puppyName").Value;
    }

Upvotes: 3

Related Questions