0

Background: I want to show a custom message box to the user with Yes/No buttons and if the user clicks each of these buttons I will return the result to the caller. Also, if the user doesn't show any reaction again I want to return a third result (using a Timer event). In a word, either after some time elapsed or after a button click the method (Display in my code) should return a value; and I want to wait for either of them to happen.

Problem: The UI looks frozen and only the Timer event triggers.

Code which will be used in the real project (with descent names!):

namespace MessageBox
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            MyForm.Display();
        }
    }
    public class MyForm : Form
    {
        public MyForm()
        {
             List<Button> _buttonCollection = new List<Button>();

            FlowLayoutPanel _flpButtons = new FlowLayoutPanel();
            Panel _plFooter = new Panel();

            _plFooter.Dock = DockStyle.Bottom;
            _plFooter.Padding = new Padding(5);
            _plFooter.BackColor = Color.FromArgb(41, 47, 139);
            _plFooter.Height = 75;
            this.FormBorderStyle = FormBorderStyle.None;
            this.BackColor = Color.FromArgb(20, 37, 105);
            this.StartPosition = FormStartPosition.CenterScreen;
            this.Padding = new Padding(3);
            this.Width = 400;
            _flpButtons.FlowDirection = FlowDirection.RightToLeft;
            _flpButtons.Dock = DockStyle.Fill;
            _plFooter.Controls.Add(_flpButtons);
            this.Controls.Add(_plFooter);
            Button btnYes = new Button();
            btnYes.Click += ButtonClick;
            btnYes.Text = "Yes";
            Button btnNo = new Button();
            btnNo.Click += ButtonClick;
            btnNo.Text = "No";
            _buttonCollection.Add(btnYes);
            _buttonCollection.Add(btnNo);
            foreach (Button btn in _buttonCollection)
            {
                btn.ForeColor = Color.FromArgb(170, 170, 170);
                btn.Font = new System.Drawing.Font("Eurostile", 12, FontStyle.Bold);
                btn.Padding = new Padding(3);
                btn.FlatStyle = FlatStyle.Flat;
                btn.Height = 60;
                btn.Width = 150;
                btn.FlatAppearance.BorderColor = Color.FromArgb(99, 99, 98);
                _flpButtons.Controls.Add(btn);
            }


        }
        static Task taskA;
        private  void ButtonClick(object sender, EventArgs e)
        {
            _event.Set();
            Button btn = (Button)sender;
            if (btn.Text == "Yes")
                Result = 1;
            else
            {
                Result = 2;
            }
            this.Close();
            this.Dispose();
        }
        static AutoResetEvent _event = new AutoResetEvent(false);
        private static MyForm form;
        public static int Display()
        {
            form = new MyForm();
            StartTimer();
            form.Show();
            _event.WaitOne();
            form.Close();
            form.Dispose();
            return Result;
        }

        private static void StartTimer()
        {
            _timer = new System.Timers.Timer(10000);
            _timer.Elapsed += SetEvent;

            _timer.AutoReset = false;
            _timer.Enabled = true;
        }

        private static System.Timers.Timer _timer;
        public static int Result { get; set; }

        private static void SetEvent(Object source, System.Timers.ElapsedEventArgs e)
        {
            _timer.Start();
            Result = -1;
            var timer = (System.Timers.Timer) source;
            timer.Elapsed -= SetEvent;
            _event.Set();
        }
    }
}

Note: I know the problem is that the UI control is created in a thread which is frozen but what's the solution?

Mohsen Kamrani
  • 7,177
  • 5
  • 42
  • 66
  • Mok, I think this is what you want. Check [here](http://stackoverflow.com/questions/14522540/close-a-messagebox-after-several-seconds) for the answer. – Marc Lyon Jan 25 '17 at 05:04
  • @MarcLyon Actually, when I was implementing this code, I looked at that code, first of all it uses hooks which I don't want to use (though I tried and it made things too complicated), secondly, there the SO doesn't need to return a value if the UI is idle. – Mohsen Kamrani Jan 25 '17 at 05:18

1 Answers1

2

Create a Dialog for MessageBox at the end of your process and show the alert you want to show the user.

You can look at the sources like and issue with Thread

Community
  • 1
  • 1
Masoud Andalibi
  • 3,168
  • 5
  • 18
  • 44