简体   繁体   中英

Modal dialog like system MessageBox in Windows Phone

I would like to make my own class for setting some values in dialog box in the way that MessageBox.Show() does.

My code is:

MainPage.xaml.cs

using System;
using System.Windows;
using Microsoft.Phone.Controls;

namespace ModalWindow
{
    public partial class MainPage : PhoneApplicationPage
    {
        public MainPage()
        {
            InitializeComponent();

            string result = MyModalBox.GiveMeValue();

            MessageBox.Show(result);
        }
    }
}

MyModalBox.cs

using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;

namespace ModalWindow
{
    public class MyModalBox
    {
        private static Popup modalBox;
        public static string GiveMeValue()
        {
            TextBox textBox = new TextBox();
            textBox.Width = 300;
            textBox.Height = 100;

            Button okButton = new Button();
            okButton.Click += okButton_Click;
            okButton.Content = "ok";
            okButton.Width = 300;
            okButton.Height = 100;

            StackPanel stack = new StackPanel();
            stack.Background = new SolidColorBrush(Colors.Black);
            stack.Width = Application.Current.Host.Content.ActualWidth;
            stack.Height = Application.Current.Host.Content.ActualHeight;
            stack.HorizontalAlignment = HorizontalAlignment.Center;
            stack.VerticalAlignment = VerticalAlignment.Center;
            stack.Children.Add(textBox);
            stack.Children.Add(okButton);

            modalBox = new Popup();
            modalBox.Child = stack;
            modalBox.IsOpen = true;

            // how to change my code to return value only after okButton is cklicked?
            return textBox.Text;
        }

        static void okButton_Click(object sender, RoutedEventArgs e)
        {
            modalBox.IsOpen = false; 
        }
    }
}

Of course it shows no result befor popup appears. How can I change my code to return value onli after clicking button? Is it possible?

Thanks in advance!

You can use TaskComplectionSource for that.

Add this:

public class DialogResult<T>
{
    private readonly T _result;
    private readonly bool _canceled;

    public DialogResult(bool isCanceled)
        : this(string.Empty, isCanceled)
    {

    }

    public DialogResult(string result, bool canceled = false)
    {
        _result = result;
        _canceled = canceled;
    }

    public T GetResults()
    {
        if (HasDialogBeenCanceled())
            throw new InvalidOperationException("Dialog has been canceled - no results");

        return _result;
    }

    public bool HasDialogBeenCanceled()
    {
        return _canceled;
    }
}

// inside your dialog control
    private TaskCompletionSource<DialogResult<string>> dialogResultAwaiter;
    private Button button;
    private TextBlock textBox;
    private Popup popup;

    public async Task<DialogResult<string>> ShowPopup()
    {
        dialogResultAwaiter = new TaskCompletionSource<DialogResult<string>>();
        button.Tapped += (sender, args) => dialogResultAwaiter.SetResult(new DialogResult<string>(textBox.Text, false));

        var popup = new Popup();
        popup.Closed += PopupOnClosed;
        // popup code
        popup.IsOpen = true;
        return await dialogResultAwaiter.Task;
    }

    private void PopupOnClosed(object sender, object o)
    {
        if (dialogResultAwaiter.Task.IsCompleted)
            return;

        dialogResultAwaiter.SetResult(new DialogResult<string>(true));
    }

In this way you can create your "own await" - which will "end" (and return results) when TaskComplectionSource.SetResult is called.

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