1

I would like to sort my Datagridview at the end of my DownloadFileCompleted event. I tried the following source which is working if it's called on a buttonClick event, but it's not with my DownloadFileCompleted event and I don't understand why.

    // Does work
    private void bt_test_1_Click(object sender, EventArgs e)
    {
        dg_logiciel.Columns[1].SortMode = DataGridViewColumnSortMode.Programmatic;
        dg_logiciel.Sort(dg_logiciel.Columns[1], ListSortDirection.Ascending);
    }

    // Does not work
    void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
    {
        // mycode
        dg_logiciel.Columns[1].SortMode = DataGridViewColumnSortMode.Programmatic;
        dg_logiciel.Sort(dg_logiciel.Columns[1], ListSortDirection.Ascending);
    }

Can someone explain me that?

5
  • Is it not working as in throwing an error, or is it not being called at all? Commented Mar 18, 2016 at 14:34
  • I don't have any problem of compilation or error messages. I put a stagging point where I'm trying to sort and it seems my code is executed but my DataGridView is never updated Commented Mar 18, 2016 at 14:51
  • 1
    I think you would have to invoke the sorting calls as the client_DownloadFileCompleted is asynchronous and thus not on your UI thread. You may have to Invoke a call to dg_logiciel to refresh the DataGridView as well. Commented Mar 18, 2016 at 15:22
  • Would look like: dg_logiciel.Invoke((MethodInvoker) delegate() { dg_logiciel.Sort(...); }); Commented Mar 18, 2016 at 15:28
  • Thanks for the help, I read the MSDN documentation about delegates and invoke method. Your idea seems good to solve my problem, but I don't understand these concepts, how does it work etc.. Could you explain me that on an easier way so I can try it? Commented Mar 18, 2016 at 15:56

1 Answer 1

1

The reason that dg_logiciel does not get updated is that the the client_DownloadFileCompleted method is being called asynchronously by whatever you're using to download in the background. This means that the the client_DownloadFileCompleted method is being called by a different thread than the one that your datagridview is on. The datagridview is on the UI Thread, and the client_DownloadFileCompleted is being called by some Worker Thread.

To get around this problem you need to send something over to the UI Thread that tells it that it needs to perform some kind of action.

This can be accomplished by calling <control>.Invoke(...) as follows:

dg_logiciel.Invoke((MethodInvoker) delegate(){ dg_logiciel.Sort(dg_logiciel.Columns[1], ListSortDirectionAscending);});

This sends a message over to the UI Thread telling it call the delegate you're passing whenever it gets a chance. In this case the delegate just has one unnamed method inside of it and all that method does is call dg_logiciel.Sort(...); The (MethodInvoker) bit, for the sake of completeness, just casts the delegate as a MethodInvoker type.

A short simple answer can be found here: How does Invoke work underneath?

I hope that helps clear it up at least a little.

Sign up to request clarification or add additional context in comments.

1 Comment

Perfect! Thank you so much for the explanation and the time you spend helping me, it was really helpful, I appreciate!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.