Showing legacy data in data grid
-
We have a legacy data struct - in C - basically a two-dimensional set of data accessible thru a C API - much like a DataTable. We want to show this data in a DataGrid and in other related controls. We're looking for a way to write our own C# wrapper class to hold the C struct, and implement the necessary interfaces so that it can be uses with the DataGrid via binding. First of all, does this approach make sense? And if it does, what interface should we implement? I've been looking at IList, but can't quite figure out how the IList interface deals with the 2-dimensional nature of our data. If anyone chooses to email me directly, remove the x's from the email address first (trying to foil the spambots). Rich
-
We have a legacy data struct - in C - basically a two-dimensional set of data accessible thru a C API - much like a DataTable. We want to show this data in a DataGrid and in other related controls. We're looking for a way to write our own C# wrapper class to hold the C struct, and implement the necessary interfaces so that it can be uses with the DataGrid via binding. First of all, does this approach make sense? And if it does, what interface should we implement? I've been looking at IList, but can't quite figure out how the IList interface deals with the 2-dimensional nature of our data. If anyone chooses to email me directly, remove the x's from the email address first (trying to foil the spambots). Rich
I would suggest that you programatically create a DataTable object, stuff it with the data to be displayed and simply point the datagrid at it (set its datasource property). If I understand your problem correctly then I believe this is the most simple way to achieve your goal. I assume that you are wanting to display the data in a datagrid as rows and columns, 2 dimensional? Is there any reason you can't use a Datatable object as you mentioned in your question?
-
I would suggest that you programatically create a DataTable object, stuff it with the data to be displayed and simply point the datagrid at it (set its datasource property). If I understand your problem correctly then I believe this is the most simple way to achieve your goal. I assume that you are wanting to display the data in a datagrid as rows and columns, 2 dimensional? Is there any reason you can't use a Datatable object as you mentioned in your question?
Thanks for the quick reply. I should have mentioned that our data can be VERY large - 100,000+ rows. Obviously we wouldn't want to copy all of that data over to a Datatable before displaying it, plus the duplication of all of that memory. That's why I thought if we could implement a set of interface methods that access the data from our own source, it might be a reasonable approach.
-
Thanks for the quick reply. I should have mentioned that our data can be VERY large - 100,000+ rows. Obviously we wouldn't want to copy all of that data over to a Datatable before displaying it, plus the duplication of all of that memory. That's why I thought if we could implement a set of interface methods that access the data from our own source, it might be a reasonable approach.
Ahh right. Well then implement an IList class just as you had planned. If we call your class Bob then use Bob's Item to store each of your structs. Thats the 2D element you were missing! Implement the IList.Add and additionally override Bobs Add mthd with one for the type of the struct. Do this with Remove and whatever else you'll need and you might want to do this with an indexer as well just to make access easy if you're using it for other things outside the grid. hope that helps.
-
Ahh right. Well then implement an IList class just as you had planned. If we call your class Bob then use Bob's Item to store each of your structs. Thats the 2D element you were missing! Implement the IList.Add and additionally override Bobs Add mthd with one for the type of the struct. Do this with Remove and whatever else you'll need and you might want to do this with an indexer as well just to make access easy if you're using it for other things outside the grid. hope that helps.
Thanks again, but that won't do it. The api for our data "object" uses row and column indexing to access the data using the public API - for example - void* TABLE_GetValue(TablePtr table, int column, int row); I guess what I'm asking is what interface and methods must be implemented so that two-dimensional data can be displayed in the datagrid? Thanks
-
Thanks again, but that won't do it. The api for our data "object" uses row and column indexing to access the data using the public API - for example - void* TABLE_GetValue(TablePtr table, int column, int row); I guess what I'm asking is what interface and methods must be implemented so that two-dimensional data can be displayed in the datagrid? Thanks
So the grid would look something like this right? RowNum ColNum Data ------- ------- ---------------------- 0 0 some data here 0 1 some more data 1 0 data 3 fe 1 1 yet more data if so, I see no problem with my earlier suggestion, the objects stored in IList impl would be the result from SomeType* TABLE_GetValue(TblPtr tbl,int col,int row) times n rows for the grid so the list would look like: 0,0,somedata 0,1,somemoredata etc... Is that what we are going for? If so then maybe some sample code from me would help! Let me know
-
So the grid would look something like this right? RowNum ColNum Data ------- ------- ---------------------- 0 0 some data here 0 1 some more data 1 0 data 3 fe 1 1 yet more data if so, I see no problem with my earlier suggestion, the objects stored in IList impl would be the result from SomeType* TABLE_GetValue(TblPtr tbl,int col,int row) times n rows for the grid so the list would look like: 0,0,somedata 0,1,somemoredata etc... Is that what we are going for? If so then maybe some sample code from me would help! Let me know
Wow - I really do appreciate your help here! Ok - you seem to be saying that we have an array of row structs - and the IList can simply give access to a row struct. This is not the case (well, it actually is the case in the internal implementation of our object, but not via the external API that I am using). Via our API, the individual cell values from our table are accessed by specifying column and row to the api - one cell at a time - There is no actual row struct that is externally available - I probably missated this in a previous post. It's more of an array of arrays - that is, an array of rows. In any event, the row arrays do not hold row and column numbers as you indicate (0,0,somedate). Rather, the rows hold an array of void*, each one representing a value for a cell. For example, a 4x4 table looks like this: row 0: ptr, ptr, ptr, ptr row 1: ptr, ptr, ptr, ptr row 2: ptr, ptr, ptr, ptr row 3: ptr, ptr, ptr, ptr where the offset into the row array is simply the column number. So we access a cell by using TABLE_GetValue(table, col, row); There actually is no access for a row since there is no row object or struct concept externally. I guess I've taken a long time saying that this is really like a simple 2-dimensional array with an cell-level access API around it. Even if I were to return some sort of Row representation by the Item() method, how would the DataGrid know what to do with that row - how to get the values for the individual cells in a row. Would it be expecting the row to also implement IList - so that it essentially would be getting an IList containing a set of ILists? thanks Rich
-
Wow - I really do appreciate your help here! Ok - you seem to be saying that we have an array of row structs - and the IList can simply give access to a row struct. This is not the case (well, it actually is the case in the internal implementation of our object, but not via the external API that I am using). Via our API, the individual cell values from our table are accessed by specifying column and row to the api - one cell at a time - There is no actual row struct that is externally available - I probably missated this in a previous post. It's more of an array of arrays - that is, an array of rows. In any event, the row arrays do not hold row and column numbers as you indicate (0,0,somedate). Rather, the rows hold an array of void*, each one representing a value for a cell. For example, a 4x4 table looks like this: row 0: ptr, ptr, ptr, ptr row 1: ptr, ptr, ptr, ptr row 2: ptr, ptr, ptr, ptr row 3: ptr, ptr, ptr, ptr where the offset into the row array is simply the column number. So we access a cell by using TABLE_GetValue(table, col, row); There actually is no access for a row since there is no row object or struct concept externally. I guess I've taken a long time saying that this is really like a simple 2-dimensional array with an cell-level access API around it. Even if I were to return some sort of Row representation by the Item() method, how would the DataGrid know what to do with that row - how to get the values for the individual cells in a row. Would it be expecting the row to also implement IList - so that it essentially would be getting an IList containing a set of ILists? thanks Rich
Let me give you some source code. Check back friday mid day or so.
-
Wow - I really do appreciate your help here! Ok - you seem to be saying that we have an array of row structs - and the IList can simply give access to a row struct. This is not the case (well, it actually is the case in the internal implementation of our object, but not via the external API that I am using). Via our API, the individual cell values from our table are accessed by specifying column and row to the api - one cell at a time - There is no actual row struct that is externally available - I probably missated this in a previous post. It's more of an array of arrays - that is, an array of rows. In any event, the row arrays do not hold row and column numbers as you indicate (0,0,somedate). Rather, the rows hold an array of void*, each one representing a value for a cell. For example, a 4x4 table looks like this: row 0: ptr, ptr, ptr, ptr row 1: ptr, ptr, ptr, ptr row 2: ptr, ptr, ptr, ptr row 3: ptr, ptr, ptr, ptr where the offset into the row array is simply the column number. So we access a cell by using TABLE_GetValue(table, col, row); There actually is no access for a row since there is no row object or struct concept externally. I guess I've taken a long time saying that this is really like a simple 2-dimensional array with an cell-level access API around it. Even if I were to return some sort of Row representation by the Item() method, how would the DataGrid know what to do with that row - how to get the values for the individual cells in a row. Would it be expecting the row to also implement IList - so that it essentially would be getting an IList containing a set of ILists? thanks Rich
Okay, here is some sample code. Sorry it's not real orderly but I just don't have time to make it real nice. I think you'll get the idea though. this code will populate a datagrid with three columns times x rows (just an exmaple, you could have as many columns as you like) from a mock of what I think your API looks like. Here is the form --------------------------------------------------------------- using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; namespace SampleOfIList { /// /// Summary description for Form1. /// public class Form1 : System.Windows.Forms.Form { private System.Windows.Forms.DataGrid dataGrid1; /// /// Required designer variable. /// private System.ComponentModel.Container components = null; public Form1() { InitializeComponent(); } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.dataGrid1 = new System.Windows.Forms.DataGrid(); ((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).BeginInit(); this.SuspendLayout(); // // dataGrid1 // this.dataGrid1.DataMember = ""; this.dataGrid1.HeaderForeColor = System.Drawing.SystemColors.ControlText; this.dataGrid1.Location = new System.Drawing.Point(8, 8); this.dataGrid1.Name = "dataGrid1"; this.dataGrid1.Size = new System.Drawing.Size(640, 160); this.dataGrid1.TabIndex = 0; // // Form1 // this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); this.ClientSize = new System.Drawing.Size(656, 197); this.Controls.Add(this.dataGrid1); this.Name = "Form1"; this.Text = "Form1"; this.Load += new System.EventHandler(this.Form1_Load); ((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).EndInit(); this.ResumeLayout(false); } #endregion /// /// The main entry point for the application. /// [STAThread] static void Main() { Application.Run(new Form1()); }