# Visual Basic > Visual Basic FAQs >  Classic VB - How do the ReadProperties and WriteProperties work? (PropertyBags)

## Merri

PropertyBags are what are used to store the control properties. Each control has one propertybag and this includes UserControls. Contents of the propertybag are shown to the developer only in the development time: so those are what you see in the Properties Window which is often placed in the right side of the screen (as it is the default position for it).


ReadProperties

The "funny" thing is that you don't need to explicitly define the properties anywhere else: they are automagically detected by Visual Basic from ReadProperties and WriteProperties. The use is simple:


VB Code:
Private Const m_def_AutoRedraw As Boolean = False
 Dim m_AutoRedraw As Boolean
 Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
    m_AutoRedraw = PropBag.ReadProperty("AutoRedraw", m_def_AutoRedraw)
    Set UserControl.Font = PropBag.ReadProperty("Font", UserControl.Extender.Container.Font)
    UserControl.AutoRedraw = m_AutoRedraw
End Sub

As you can see, in this example we have two different kinds of properties: a variable and an object. The object is set directly to the control and the effect is immediate. The AutoRedraw however uses a temporary variable and a constant value. This is close to the default way things are done when creating an automated usercontrol and I see no reason not to do this in other way. Thus: constants in the code are "easy to change default settings". The font by default is copied from the container of the usercontrol. This is how VB controls behave by default.

Also noticeable is that the AutoRedraw setting is also set afterwards to effect: basically you need to do the redrawing of the control in ReadProperties, otherwise your control would appear odd-looking if you draw it with your own code.


WriteProperties

WriteProperties is more straightforward:


VB Code:
Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
    PropBag.WriteProperty "AutoRedraw", m_AutoRedraw, m_def_AutoRedraw
    PropBag.WriteProperty "Font", UserControl.Font, UserControl.Extender.Container.Font
End Sub

It is only used to save the settings. First comes the property name, then the value to be saved and last the default value, which is optional.


Some notes about PropertyBags

Apparently strings are always stored in ANSI format, so you lose Unicode characters if you try to save those or use such as a default value. You can of course skip the problem by using StrConv, though it might cause problems. This far I've decided not to save Unicode at all. This isn't a critical issue though, often Unicode supported controls are filled afterwards.



Comments and feedback
If you're not adding any new information in to the reply, send me a private message instead  :Smilie:

----------


## LaVolpe

Another tidbit or two about these usercontrol events.

Where are these properties actually written to and read from? The answer is in one of two places.  Each form has a .frm file and may have a .frx file that VB will create as needed. Both these files can be viewed in WordPad and NotePad, though the .frx file can contain binary data.  The usercontrols that exist on that form have their data written to that form's .frm and/or .frx files.

1. Simple properties like booleans, long, integer, small strings, etc may be written to the .frm file.

2. Arrays, objects, long strings, and other data may be written to the form's .frx file

-------------------------------------------------------------------------

When writing a property, the property may actually not be written! You may not see it in the .frm file or the .frx file when viewed in WordPad.  Why not? The answer is it has to do with default settings.  The 3rd parameter of the PropertyBag.WriteProperty method is the default value. If the 2nd parameter and 3rd parameter are equal, the property is not written.  Because of that, you should always supply the same default value to the 2nd parameter of the .ReadProperty method. That method uses the 2nd parameter as the property value if the property was not written. Notice that vbButtonFace is used as the same default during both reading and writing.

vb Code:
Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
    m_bkColor = PropBag.ReadProperty("BackColor", vbButtonFace)
    ' if property does not exist, m_bkColor will be set to vbButtonFace
End Sub 
 Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
   PropBag.WriteProperty "BackColor", m_bkColor, vbButtonFace
   ' if m_bkColor=vbButtonFace, property is not written
End Sub

-------------------------------------------------------------------------

The only array VB can store in its property bag is a one-dimensional byte array.  Some usercontrols need to save lists.  Since the list may very well be string data, here is an easy way to save and read a string array.

vb Code:
Dim myListing() As String
 Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
    myListing() = Split(PropBag.ReadProperty("ListItems", vbNullString), Chr$(8))
    ' if property does not exist, UBound(myListing)=-1
End Sub 
 Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
   PropBag.WriteProperty "ListItems", Join(myListing(), Chr$(8)), vbNullString
End Sub
Saving an array of other datatypes would require converting those datatypes to a byte array or saving each array item as a separate property.

----------

