C # Winforms: выборочное отключение пользовательского интерфейса во время работы потока - PullRequest
4 голосов
/ 25 января 2012

У меня довольно сложная форма, которая предоставляет возможность запуска скрипта (нашего собственного типа).Пока он работает, я не хочу полностью блокировать пользовательский интерфейс, поэтому я хотел бы запустить его в потоке.Пока все хорошо, но чтобы пользователь не мешал, мне нужно выборочно отключать части пользовательского интерфейса.Я мог бы рекурсивно установить Enabled = false, а затем Enabled = true, когда поток заканчивается.Но это игнорирует состояние элемента управления во время работы (т. Е. Элементы управления, которые были отключены по разным причинам, были бы неправильно повторно включены).Если не считать дерево логических значений, есть ли другой способ блокировать ввод (например, тип GlassPane в Java)?

Ответы [ 3 ]

3 голосов
/ 25 января 2012

Не используйте DoEvents, это зло .

Используйте панель и добавьте в нее все элементы управления, которые вы хотите отключить.Когда панель будет отключена, все внутренние элементы управления будут отключены, но значение их свойства Enabled фактически не будет изменено.

Вот рабочий пример:

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // Disables UI elements using the panel
            this.SetPanelEnabledProperty(false);

            // Starts the background work
            System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(this.Worker));
        }

        private void Worker(object state)
        {
            // Simulates some work
            System.Threading.Thread.Sleep(2000);

            // Now the work is done, enable the panel
            this.SetPanelEnabledProperty(true);
        }

        private void SetPanelEnabledProperty(bool isEnabled)
        {
            // InvokeRequired is used to manage the case the UI is modified
            // from another thread that the UI thread
            if (this.panel1.InvokeRequired)
            {
                this.panel1.Invoke(new MethodInvoker(() => this.SetPanelEnabledProperty(isEnabled)));
            }
            else
            {
                this.panel1.Enabled = isEnabled;
            }
        }
    }
1 голос
/ 25 января 2012

Не могли бы вы использовать панель, заполненную элементами управления, которые вы хотите отключить во время выполнения сценария, а затем повторно включить панель после завершения сценария.

В качестве альтернативы вы можете запустить Процесс для сценария.

0 голосов
/ 25 января 2012

Вы можете решить эту проблему либо с помощью метода Application.DoEvents (), либо вы должны написать делегат, который вызывает соответствующий элемент управления.Я думаю, что Application.DoEvents () будет самым простым способом.Вы должны вызвать Application.DoEvents () в цикле вашего потока.

Для версии делегата вы найдете здесь некоторую информацию: http://msdn.microsoft.com/de-de/library/zyzhdc6b.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...