PiggyBank1974 Posted October 4, 2009 Posted October 4, 2009 Hi There, As I know VB.net miles better than C# I've been creating a Dll that will handle a SQLCE database on a windows mobile device. I have most of it working ok But I'm trying to convert this method below for VB(Full .net framework), to Compact framework using C# But I'm a little stuck. The idea of the function is to use reflection and fill a custom ListviewItems class with information from the database this works great in Full .net framework, but not in CE so far. VB.net version is: Public Function GetRecords(ByVal MSLV As Object, ByVal Query As String, ByVal T As Type) As List(Of Windows.Forms.ListViewItem) Dim mProperty As PropertyInfo Dim mList As List(Of ListViewItem) = New List(Of ListViewItem) Dim Da As OleDbDataAdapter = New OleDbDataAdapter(Query, mDbConnection) Dim Ds As DataSet = New DataSet("Blank") Da.Fill(Ds, "Blank") For Each table As DataTable In Ds.Tables For Each row As DataRow In table.Rows Dim mobj As Object = Activator.CreateInstance(T) ' If the first column is the same as the for column in the row set the text. If MSLV.Columns(0).Tag = table.Columns.Item(0).ColumnName Then mobj.text = row(table.Columns.Item(0).ColumnName) End If For Each LVColumn As System.Windows.Forms.ColumnHeader In MSLV.Columns ' Skip the first column as this is the items column not the sub items column. If MSLV.Columns(0).Tag <> LVColumn.Tag Then ' Make sure the column is in the row columns list or it will fail. If row.Table.Columns.Contains(LVColumn.Tag) = True Then mobj.subitems.add(row(LVColumn.Tag)) End If End If Next LVColumn For Each column As DataColumn In table.Columns mProperty = T.GetProperty(column.ColumnName) If mProperty IsNot Nothing Then mProperty.SetValue(mobj, row(column.ColumnName), Nothing) End If Next column mList.Add(mobj) Next row Next table Return mList End Function C# version public List<ListViewItem> GetRecords(Object MSLV, string Query, Type T) { if (mSqlCeConnection.State == System.Data.ConnectionState.Open) { PropertyInfo mProperty; List<ListViewItem> mList = new List<ListViewItem>(); SqlCeDataAdapter DA = new SqlCeDataAdapter(Query, mSqlCeConnection); DataSet DS = new DataSet("Blank"); DA.Fill(DS, "Blank"); foreach (DataTable table in DS.Tables) { foreach (DataRow row in table.Rows) { Object mobj = Activator.CreateInstance(T); // If the first column is the same as the for column in the row set the text. if (MSLV.Columns[0].Text == table.Columns[0].ColumnName) { mobj.Text = row[table.Columns[0].ColumnName]; } foreach (ColumnHeader LVColumn in MSLV.Columns) { // Skip the first column as this is the items column not the sub items column. if (MSLV.Columns[0].Text != LVColumn.Text) { // Make sure the column is in the row columns list or it will fail. if (row.Table.Columns.Contains(LVColumn.Text) == true) { mobj.SubItems.Add(row[LVColumn.Text]); } } } foreach (DataColumn column in table.Columns) { mProperty = T.GetProperty(column.ColumnName); if (mProperty != null) { mProperty.SetValue(mobj, row[column.ColumnName], null); } } mList.Add(mobj); } } return mList; } return null; } The problem is on the C# version it errors on these 'object' does not contain a definition for 'Columns' and no extension method 'Columns' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?) 'object' does not contain a definition for 'Text' and no extension method 'Text' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?) 'object' does not contain a definition for 'Columns' and no extension method 'Columns' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?) 'object' does not contain a definition for 'Columns' and no extension method 'Columns' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?) 'object' does not contain a definition for 'SubItems' and no extension method 'SubItems' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?) The best overloaded method match for 'System.Collections.Generic.List<System.Windows.Forms.ListViewItem>.Add(System.Windows.Forms.ListViewItem)' has some invalid arguments Argument '1': cannot convert from 'object' to 'System.Windows.Forms.ListViewItem' It probably because its a heavily typed language? Also MSLV is a custom Listview. and the T parameter is and inherited ListviewItem class I ant to use. can anybody help? Quote
Administrators PlausiblyDamp Posted October 5, 2009 Administrators Posted October 5, 2009 C# is a strongly typed language (like VB with option strict turned on) and as such will verify the existence of methods etc. on your variables at compile time. In the code you have a couple of variables (MSLV and mobj) that are declared as object - this means the existence of methods / properties such as Columns, Text etc. cannot be done by the compiler - you would need to either strongly type the variables or cast them to the correct type before using them. One thing you could do is to change the method definition to strongly type the MSLV parameter e.g. public List GetRecords(ListView MSLV, string Query, Type T) this should remove several errors to begin with. If the parameter T just defines which type of listviewitem you are using then you could move this to the generic declaration part as well and this would allow you to use more strongly typed code as well. public List GetRecords(ListView MSLV, string Query) where LVI : ListViewItem, new() { if (mSqlCeConnection.State == System.Data.ConnectionState.Open) { PropertyInfo mProperty; List mList = new List(); SqlCeDataAdapter DA = new SqlCeDataAdapter(Query, mSqlCeConnection); DataSet DS = new DataSet("Blank"); DA.Fill(DS, "Blank"); foreach (DataTable table in DS.Tables) { foreach (DataRow row in table.Rows) { LVI mobj = new LVI(); // If the first column is the same as the for column in the row set the text. if (MSLV.Columns[0].Text == table.Columns[0].ColumnName) { mobj.Text =(string) row[table.Columns[0].ColumnName]; } foreach (ColumnHeader LVColumn in MSLV.Columns) { // Skip the first column as this is the items column not the sub items column. if (MSLV.Columns[0].Text != LVColumn.Text) { // Make sure the column is in the row columns list or it will fail. if (row.Table.Columns.Contains(LVColumn.Text) == true) { mobj.SubItems.Add((string) row[LVColumn.Text]); } } } foreach (DataColumn column in table.Columns) { Type T = mobj.GetType(); mProperty = T.GetProperty(column.ColumnName); if (mProperty != null) { mProperty.SetValue(mobj, row[column.ColumnName], null); } } mList.Add(mobj); } } return mList; } return null; } The only thing I was unsure of is the loop towards the end where you are looping over the DataColumns - the code above should mimic your original code however. Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.