Элементы управления c # Winform с надстройкой VSTO обеспечивают отзывчивость Excel

Я новичок в надстройке VSTO Excel и Winforms. Я создал надстройку, которая запускает страницу winform с несколькими флажками, кнопкой и одной меткой для отслеживания статуса.

введите здесь описание изображения

Как только запускается winform, мой excel не реагирует. Я хотел бы, чтобы excel реагировал даже при открытом winform (и при нажатии кнопки «Готово»). Кнопка запустит длительный процесс. Как я могу этого добиться? Есть указатели?

Вот что у меня есть класс ленты:

public partial class Ribbon1
    {
        private void Ribbon1_Load(object sender, RibbonUIEventArgs e)
        {

        }

        private void button1_Click(object sender, RibbonControlEventArgs e)
        {
            Form1 fs = new Form1();
            fs.ShowDialog();
        }

    }

Класс формы:

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

        private async void button1_Click(object sender, EventArgs e)
        {
            label1.Text = "Processing please wait";
            await Task.Run(() => { longRunningProcess(); });
            label1.Text = "File 1 Processed";
        }
         public void longRunningProcess()
        {
            Thread.Sleep(5000);
        }
    }

Обновление: использование .show работает, но я не могу получить доступ к label1.Text и получить сообщение об ошибке:

System.InvalidOperationException: 'Cross-thread operation not valid: Control 'label1' accessed from a thread other than the thread it was created on.'

введите здесь описание изображения


person ProgSky    schedule 06.08.2018    source источник
comment
Попробуйте открыть форму с помощью: «Показать»   -  person Sievajet    schedule 06.08.2018
comment
Будьте осторожны: если вам нужно внести изменения в объектную модель Excel после закрытия этого окна, вы должны оставить его модальным или переместить в область действий / задач.   -  person Chris    schedule 06.08.2018
comment
@Sievajet «Показать» работает, но строка label1.Text = Файл 1 обработан; выходит из строя с ошибкой. Межпоточная операция недействительна: к элементу управления label1 осуществляется доступ из потока, отличного от потока, в котором он был создан.   -  person ProgSky    schedule 06.08.2018
comment
Используйте Invoke для маршалинга в поток пользовательского интерфейса.   -  person Sievajet    schedule 06.08.2018
comment
@Sievajet благодарит за указатель. с этой строкой это работает: label1.Invoke ((MethodInvoker) delegate {label1.Text = Test;});   -  person ProgSky    schedule 06.08.2018
comment
@Sievajet Не могли бы добавить свой ответ? так что я могу отметить как принятое решение.   -  person ProgSky    schedule 06.08.2018


Ответы (2)


Откройте форму с помощью Show и используйтеInvoke для маршалинга обратно в поток пользовательского интерфейса.

person Sievajet    schedule 06.08.2018

@Sievajet помог решить эту проблему. Почтовый индекс, на случай, если он кому-то понадобится.

private async void button1_Click(object sender, EventArgs e)
        {
            label1.Text = "Processing please wait";
            await Task.Run(() => { longRunningProcess(); });
            label1.Invoke((MethodInvoker)delegate {
                label1.Text = "File 1 Processed";
            });
        }
person ProgSky    schedule 06.08.2018
comment
На самом деле вам не нужен Invoke, потому что продолжение после Await будет опубликовано в ветке пользовательского интерфейса. - person Sievajet; 06.08.2018
comment
И если он все еще вызывает исключение пользовательского интерфейса. Вы, вероятно, инициировали обновление или ожидаете в рабочем потоке. Ожидание необходимо вызвать в потоке пользовательского интерфейса, чтобы продолжить в этом потоке. - person Sievajet; 06.08.2018
comment
Спасибо. Я изучу это подробнее. - person ProgSky; 06.08.2018