1
votes

I am new to VSTO Excel Addin and Winforms. I have created an addin, which launches a winform page with few check boxs, a button and one label to tract status.

enter image description here

As soon as the winform launches, my excel is not responsive. I would like to make excel responsive even with winform open (and with button "Done" click). Button will run a long running process. How can I achieve that? Any pointers?

This is what I have Ribbon Class:

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();
        }

    }

Form Class:

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);
        }
    }

Update: Using .show works but I am unable to access label1.Text and get error as :

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

enter image description here

2
Try open your form with: ‘Show’Sievajet
Beware: if you need to make changes to the Excel object model after this window closes, you should keep it modal or move it into an action/task pane.Chris
@Sievajet 'Show' works but line label1.Text = "File 1 Processed"; fails with error. Cross-thread operation not valid: Control 'label1' accessed from a thread other than the thread it was created on.ProgSky
Use ‘Invoke’ to marshal to the UI threadSievajet
@Sievajet thanks for the pointer. with this line it works : label1.Invoke((MethodInvoker)delegate { label1.Text = "Test"; });ProgSky

2 Answers

1
votes

Open your form with Show and useInvoke to marshal back to the UI thread.

1
votes

@Sievajet helped solve this. Posting code, in case someone needs it.

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";
            });
        }