Solved

Use a Dataset to store Property Information

Posted on 2011-09-16
11
287 Views
Last Modified: 2012-05-12
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
Comment
Question by:Peter Allen
  • 6
  • 4
11 Comments
 
LVL 25

Expert Comment

by:Luis Pérez
ID: 36548726
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
 
LVL 15

Expert Comment

by:x77
ID: 36550040
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
 

Author Comment

by:Peter Allen
ID: 36554277
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
 
LVL 15

Expert Comment

by:x77
ID: 36554728

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
 

Author Comment

by:Peter Allen
ID: 36556269
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
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 15

Expert Comment

by:x77
ID: 36556319
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
 

Author Comment

by:Peter Allen
ID: 36556352
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
 

Author Comment

by:Peter Allen
ID: 36556376
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
 

Author Comment

by:Peter Allen
ID: 36556421
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
 
LVL 15

Accepted Solution

by:
x77 earned 250 total points
ID: 36556638
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
 

Author Closing Comment

by:Peter Allen
ID: 36561285
The solution was a bit hard to follow.
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Well, all of us have seen the multiple EXCEL.EXE's in task manager that won't die even if you call the .close, .dispose methods. Try this method to kill any excels in memory. You can copy the kill function to create a check function and replace the …
Article by: Kraeven
Introduction Remote Share is a simple remote sharing tool, enabling you to see, add and remove remote or local shares. The application is written in VB.NET targeting the .NET framework 2.0. The source code and the compiled programs have been in…
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

759 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now