简体   繁体   中英

C# WPF Pause processing until button has been pressed

I decided to create my own dialog windows in WPF. I have it working using a Frame and navigating to a WPF page in the frame to get the appropriate dialog window I previously made. The problem comes when trying to return a value. For example if I have 'ok' and 'cancel' I would want to return a Boolean value upon pressing 'ok' or 'cancel' on the page displayed in the frame.

//This is what I'm using to display the dialog window frame.
public bool DisplayQuestion(string subject, string message)
    {
        AlertIsUp = true;
        var questionPage = new QuestionPage(AlertFrame, subject, message);
        AlertFrame.Navigate(questionPage);
        if (MainFrame.Content != null && MainFrame.Content.ToString() == "System.Windows.Controls.WebBrowser")
        {
            MainFrame.Visibility = System.Windows.Visibility.Hidden;
        }

        //I need it to wait until a button on the dialog frame is pressed before continuing.
        return QuestionResponse;
    }

What happens is that is will immediately return the Boolean value which of course is always false. I need it to wait until 'ok' or 'cancel' are pressed within the page and then continue on to return it's value.

Here is the code within the page.

Frame AlertFrame { get; set; }
public bool AlertIsUp { get; set; }
public bool QuestionResponse { get; set; }

public QuestionPage(Frame alertFrame, string subject, string message)
{
    InitializeComponent();
    theMesssage.Content = message;
    subjectLabel.Content = subject;
    AlertFrame = alertFrame;
    AlertIsUp = MainWindow.AlertIsUp;
    QuestionResponse = MainWindow.QuestionResponse;

}

private void CancelButton_Click(object sender, RoutedEventArgs e)
{
    AlertFrame.Content = null;
    AlertIsUp = false;
    QuestionResponse = false;
}

private void OkButton_Click(object sender, RoutedEventArgs e)
{
    AlertFrame.Content = null;
    AlertIsUp = false;
    QuestionResponse = true;
}

Of course if I just add While(AlertIsUp) then if freezes the GUI. It is very possible that I am doing things backward since I have not taken any formal training in C#. Thank you for your kind responses to my first post on this site.

I actually found a solution to this problem here:

http://www.codeproject.com/Articles/36516/WPF-Modal-Dialog

The solution ended up placing this short piece of code:

while (AlertIsActive)
    {
        if (this.Dispatcher.HasShutdownStarted ||
            this.Dispatcher.HasShutdownFinished)
        {
            break;
        }

        this.Dispatcher.Invoke(
            DispatcherPriority.Background,
            new ThreadStart(delegate { }));
        Thread.Sleep(20);
    }

You can create a delegate in your dialog Window and attach a handler from the same method that creates and shows it. Then you can call the delegate when the Button is clicked and the launching class will get called. You'll then know the value and be able to close the Window .

If you don't know about delegate s then you should definitely read the Delegates (C# Programming Guide) page on MSDN to help you understand this solution. You could do something like this:

In your dialog Window :

public void delegate Response(bool response);

public Response OnButtonClick { get; set; }

Then in the code that launches the dialog Window :

DialogWindow dialogWindow = new DialogWindow();
dialogWindow.OnButtonClick += OnButtonClick;
dialogWindow.Show();

...

public void OnButtonClick(bool response)
{
    if (response) { /* Ok */ }
    else { /* Cancel */ }
}

UPDATE >>>

Apologies for forgetting to show you the crucial part. When the Button is clicked, the dialog Window calls the delegate :

private void CancelButton_Click(object sender, RoutedEventArgs e)
{
    AlertFrame.Content = null;
    AlertIsUp = false;
    QuestionResponse = false;
    if (OnButtonClick != null) OnButtonClick(QuestionResponse);
}

private void OkButton_Click(object sender, RoutedEventArgs e)
{
    AlertFrame.Content = null;
    AlertIsUp = false;
    QuestionResponse = true;
    if (OnButtonClick != null) OnButtonClick(QuestionResponse);
}

Of course, you won't really have much need for your QuestionResponse property and you could just as easily return true or false in the QuestionResponse delegate . Once that is called, the handler will get the response.

Regarding your comment about you not using different Window s, it makes little difference with delegate s, it will work just the same. You can use them when there's no UI involved at all.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM