Solved

Use a Dataset to store Property Information

Posted on 2011-09-16
11
296 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
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
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
 
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

Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
vb.net help 4 34
Footer for each row on Gridview 2 33
Help with consolidating excel files using VB.net 2 29
VB.Net Determine if a mapped network drive exists 2 32
Microsoft Reports are based on a report definition, which is an XML file that describes data and layout for the report, with a different extension. You can create a client-side report definition language (*.rdlc) file with Visual Studio, and build g…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
This video shows how to quickly and easily add an email signature for all users on Exchange 2016. The resulting signature is applied on a server level by Exchange Online. The email signature template has been downloaded from: www.mail-signatures…
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…

820 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