Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 315
  • Last Modified:

Use a Dataset to store Property Information

Experts,

I am working with a DataGridView control builder.  This Builder allows a user to select a DataSource and customize the DataGridView.  All of the settings would be saved to an XML file which can be called by one Function and re-displayed.  I can quickly use this builder to create a library of DataGridViews in any of my applications and not have to wory about individually coding each DataGridView.  This will make for MUCH faster application developement and display of data for my customers.

I store the data for the DataGridView in a DataSet.  This makes it easy to poass all of the necessary settings.  Creating the structure of the dataset is not my problem, nor is creating XML files.  The issue I am having now is storing the information for the Public Properties in a DataTable and calling them back later.

Say I have a Table called "Properties".  This table has three columns; 1) PropertyName, 2) PropertyVariable, and 3) PropertyValue.

1. PropertyName is the abbreviated name of the Public Property Setting.  2) PropertyVariable is the FULL Public Propery Variable.  3) ProperyValue is the actual value for the Public Property.  I know I can use Reflection to iterate Public Properties, but to store, Set and Get the value is my major issue right now.

Using PropertyInfo (pInfo) I can loop through the Public Properties and get the Name of the Public Property.  I store this name in column 2 (PropertyName).  How do I Get the value of the Public Property to store in (PropertyValue)?  And also do the reverse which is to Set the value once read from column 3?  At this point I am using a loop (iLoop) and want to take the PropertyName, match it to the Public Propery and Set the value.  Could you show me a sample of code for this?
0
Peter Allen
Asked:
Peter Allen
  • 6
  • 4
1 Solution
 
Luis PérezSoftware Architect in .NetCommented:
If you know the name of a property, you can use CallByName to call that property for any object. For example, suppose you have a TextBox and you want to get/set its Text property, but you don't know if the object is a TextBox and you only got the name of the property. Look at the example:

Dim myObject As Object = Me.TextBox1
Dim propertyName As String = "Text"

'To get the value
Dim propertyValue As String = CallByName(myObject, propertyName, CallType.Get) 'Or you can dim propertyValue As Object if you don't know the data type

'To set the value
CallByName(myObject, propertyName, CallType.Let, newValue)

Hope that helps.
0
 
x77Commented:
You can use GetValue an SetValue to get / set Values from Properties and also on members:

    Const RefBF As BindingFlags = BindingFlags.Public Or BindingFlags.NonPublic Or BindingFlags.Instance

    dim PageInfo As FieldInfo = GetType(PrintPreviewControl).GetField("pageInfo", RefBF)
    Dim x As PropertyInfo = GetType(PrintPreviewControl).GetProperty("Name", RefBF)

Properties:

                x.SetValue(Dlg.PrintPreviewControl, "Nuevo", Nothing)
                Debug.Print(x.GetValue(Dlg.PrintPreviewControl, Nothing).ToString())

Members:
                PageInfo.SetValue(Dlg.PrintPreviewControl, Pages) ' Fill PageInfo with Reflection
0
 
Peter AllenAuthor Commented:
I know the Property name because I have that defined in a table.  I also know the type of the object wheather it is ingeter, etc.  Here is an example:

I have a Form called DataSourceLink.  On DataSourceLink I have Public Properties defined from class clsProp_DataSourceLinkProperties.  One of the members of the class is a Public Property called DataSetName.  On Form DataSetLink I have a TextBox called DataSetName as well.  The value I entered into the TextBox is "Temp".

Given the above I want to store the value of the Property in column 3 of my table in the dataset I will write to an XML file.  So I want to iterate throuth the properties of the class to get the value of the property for DataSetName using GetValue froim the PropertyInfo.  What would the code in VB look like for this example.  I would also like to see an example of SetValue using the same information provided.  Each time I try to write the code I get an error.

I hope this clears things up a bit more.  The class I am writing can be used on several different forms to help save and subsiquently recall data from the XML file.
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
x77Commented:

Sub Save(FormType as Type, Frm As Form, MyTable as DataTable)  
   Dim properties = FormType.GetProperties 'Only Public Properties

   For Each prop As PropertyInfo In properties
      Dim Row = MyDataTable.rows.NewRow
      Row("Form") = Frm.Name
      Row("Property") = prop.Name
      Row("Value") =prop.GetValue(Frm, Nothing)
      rows.add(row)
   Next
end sub

'Asume Primary Key - Form,Property
Sub Restore(FormType as Type, Frm As Form, MyTable as DataTable)  
   Dim properties = FormType.GetProperties 'Only Public Properties
   Dim Key(1) as object
   Key(0) = Frm.Name
   For Each prop As PropertyInfo In properties
      Key(1)= prop.Name
      dim Row = MyTable.Rows.Find(key)
      if Row isnot nothing then prop.SetValue(Frm, Row("Value"), Nothing)
   Next
end sub


0
 
Peter AllenAuthor Commented:
x77,

I get an error on the first line 'Dim properties as FormType.GetProperties.

While FormType is Type it doesn't seam to map to GetType.  I believe I understand the subroutine, but could you exlain this.  Do I need to add any other imports besides System.Reflection?
0
 
x77Commented:
Asume you Create a Form2 Class and create an instance from Form2:

    Dim f as new Form2, Ty = Gettype(Form2)  ' Ty = f.Gettype() - you can get Type from Object and also from class.
    Restor3(Ty, f, MyTable)
    F.ShowDialog
    Save(Ty, f, MyTable)

Note that You need modify Save Method to allow Update:

Sub Save(FormType as Type, Frm As Form, MyTable as DataTable)  
   Dim properties = FormType.GetProperties 'Only Public Properties

   Dim Key(1) as object
   Key(0) = Frm.Name
   For Each prop As PropertyInfo In properties
      Key(1)= prop.Name
      dim Row = MyTable.Rows.Find(key)
      if row is nothing then
            Dim Row = MyDataTable.rows.NewRow
            Row("Form") = Frm.Name
            Row("Property") = prop.Name
            Row("Value") =prop.GetValue(Frm, Nothing)        
            rows.add(row)
      else
            Row("Value") =prop.GetValue(Frm, Nothing)   'Update Value
      end if
   Next
end sub

I wrote this code without test it.
I only intend to show concept.
   

0
 
Peter AllenAuthor Commented:
x77,

I figured out I was typing the code incorrectly.  The code works, however what do I pass as FormType parameter.  Is this the class or properties from the form I am passing?
0
 
Peter AllenAuthor Commented:
X77,

OK.  One question..

What if I am already on the form and placing a call to this subroutine?  Would I still use the same code you gave as an example?

0
 
Peter AllenAuthor Commented:
X77,

When I called this subroutine it was in a class that was declared from the Form.  So I passed the Form name as Me to the class and just before the actual subroutine was called I created ty to hold the GetType of the form being passed and then the subroutine is executed.  I get the following error:

Object type does not match  target type".

The error seams to point directly to "GetValue(prop, Nothing)".  Any ideas?
0
 
x77Commented:
This code is not complete.

I Stop when I found a Not Asignable Property (IsMdiChild).
Note that there are many exceptions to control when assign a value to a Property.

I make Conversion from String to  Object for Enumerable and also for Iconvertible.
I Avoid also save null values.

You need also Know how convert from   String  to   Size.

I Think the conversion / Parse methods you need are very Complex.
Imports System.Reflection
Module Module1

Public MyTable As DataTable
Sub Save(ByVal Frm As Form)
   Dim properties = Frm.GetType.GetProperties 'Only Public Properties

   Dim name = TypeName(Frm), Key = New Object() {name, Nothing}
   For Each prop As PropertyInfo In properties
      Dim value = prop.GetValue(Frm, Nothing)
      If value Is Nothing Then Continue For
      value = TryCast(value, IConvertible)
      If value Is Nothing Then Continue For
      Key(1) = prop.Name
      Dim Row = MyTable.Rows.Find(Key)
      If Row Is Nothing Then
         Row = MyTable.NewRow
         Row("Form") = name
            Row("Property") = prop.Name
            Row("Value") = value
            MyTable.Rows.Add(Row)
            Debug.Print("{0} {1} {2}", prop.Name, value, TypeName(value))
      Else
            Row("Value") = prop.GetValue(Frm, Nothing)   'Update Value
      End If
   Next
End Sub


'Asume Primary Key - Form,Property
Public Sub Restore(ByVal Frm As Form)
   Dim properties = Frm.GetType.GetProperties 'Only Public Properties
   Dim name = TypeName(Frm), Key = New Object() {name, Nothing}, obj As Object
   For Each prop As PropertyInfo In properties
      Key(1) = prop.Name
      Dim Row = MyTable.Rows.Find(Key)
      If Row IsNot Nothing Then
           Dim s = TryCast(Row("Value"), String)
           If prop.PropertyType.IsEnum Then
             obj = [Enum].Parse(prop.PropertyType, s)
           Else
             obj = Convert.ChangeType(S, prop.PropertyType)
           End If
           prop.SetValue(Frm, obj, Nothing)
      End If
   Next
   Stop
End Sub

Public Sub Main()
    MyTable = New DataTable
    MyTable.Columns.Add("Form")
    MyTable.Columns.Add("Property")
    MyTable.Columns.Add("Value")
    MyTable.PrimaryKey = New DataColumn() {MyTable.Columns(0), MyTable.Columns(1)}


    Dim f As New Form1
'   Restore(f)
    f.ShowDialog()
    Save(f)
    f.Dispose()


    Dim f1 As New Form1
    Restore(f1)
    f1.ShowDialog()
    Save(f1)

End Sub

End Module

Open in new window

0
 
Peter AllenAuthor Commented:
The solution was a bit hard to follow.
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 6
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now