Search code examples
c#.netwinformsdata-bindingdatagridview

Bind Datagridview from another thread while in other tabpage


I have a .net winform application, with a simply TabControl. In one TabPage there is a Datagridview. In another page i have a button that start a process in another thread. In the callback event i get received data, and i store them in a public List inside my form. After that, ever in the callback, i shot my change page command, that allow to select a different tabpage from different thread (with the BeginInvoke pattern).

public List<myClass> Params = new List<myClass>();
static void client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e){
   [...]
   // stuff to store the received data
   thisForm.Params.AddRange(cmd.Params);

   // here i select TabPage with the Datagridview with BeginInvoke
   thisForm.ChangePage(PageControl.ePages.PAGE_CHOOSE_PARAMETERS);
}

Now, when the page with datagridview is shown, the datagridview is ever empty. I tried to init the Datagridview's DataSource with Param on the Load event of the form (and obiouvsly fill the list inside the event), i tried also to init Datasource inside the event (with the BeginInvoke pattern). In many examples for bind a simple list of object to a Datagridview is enough to init DataSource, not in my case. Is the datagridview visibility the problem? Does i need to change page before datagridview initialization?

Edited for Jimi: Thanks Jimi... Yes, it's only a sample code. The problem isn't the parsing and the loading of the data inside the List, it works well... About the Change page routine, it's only a call to a routine that do something like this:

 private void SetPage(string page) {
     tabControl.BeginInvoke(new SetPageDelegate(FormThread_SetPage), page);
 }

 private void FormThread_SetPage(string page)
 {
     tabControl.SelectedTab = tabControl.TabPages[page];
 }

And it works well too, it's only a method for change page from whatever, also different thread.

About the list, it's a simple list for store all my device's parameters and their type ecc... I paste here the code of the list:

        public class Cmd_Profile_Param
        {
            [JsonProperty("Cat")]
            string Cat { get; set; }

            [JsonProperty("Name")]
            string Name { get; set; }

            [JsonProperty("Type")]
            string Type { get; set; }

            [JsonProperty("AuthRd")]
            bool AuthRd { get; set; }

            [JsonProperty("AuthWr")]
            bool AuthWr { get; set; }

            [JsonProperty("Min", NullValueHandling = NullValueHandling.Ignore)]
            double ?Min { get; set; }

            [JsonProperty("Max", NullValueHandling = NullValueHandling.Ignore)]
            double ?Max { get; set; }

            [JsonProperty("Enum", NullValueHandling = NullValueHandling.Ignore)]
            string[] Enum { get; set; }
        }

        public List<Cmd_Profile_Param> Params = new List<Cmd_Profile_Param>();

The thread is the received delegate of a mqtt client, i leave the real name of the control for understanding that i'm not in the form thread. Nothing exceptional until here.

The problem is where assign the datagridview's datasource, and invoke the Refresh method, if necessary!


Solution

  • Seems that the problem is the Cmd_Profile_Param variable's access modifier.

    I changed the class to:

     public class Cmd_Profile_Param
            {
                [JsonProperty("Cat")]
                public string Cat { get; set; }
    
                [JsonProperty("Name")]
                public string Name { get; set; }
    
                [JsonProperty("Type")]
                public string Type { get; set; }
    
                [JsonProperty("AuthRd")]
                public bool AuthRd { get; set; }
    
                [JsonProperty("AuthWr")]
                public bool AuthWr { get; set; }
    
                [JsonProperty("Min", NullValueHandling = NullValueHandling.Ignore)]
                public double ?Min { get; set; }
    
                [JsonProperty("Max", NullValueHandling = NullValueHandling.Ignore)]
                public double ?Max { get; set; }
    
                [JsonProperty("Enum", NullValueHandling = NullValueHandling.Ignore)]
                public string[] Enum { get; set; }
            }
    

    And headers will appear. But only if i assign the datasource in the form's thread i will see the data. So, for workaround, i created a button that appear on received data, and in the click event i assign the datasource.