Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie

VB Ques PropertyBags Whaa?

Options
  • 20-01-2003 9:29pm
    #1
    Closed Accounts Posts: 8,264 ✭✭✭


    .


Comments

  • Closed Accounts Posts: 9,314 ✭✭✭Talliesin


    Most of the references will be in terms of ActiveX controls, because most use of property bags is with ActiveX controls.

    When you think about how you use a control on a form the process is:
    1. Place control on form
    2. Change properties from defaults to what you want the initial settings to be.
    3. Write code which reacts to the control's events and/or manipulates the controls (calls its methods or changes its properties).

    Now for number 2 of those to work the control needs to somehow store what properties you set, and be able to read them again when the control is re-instantiated, whether because you have come back to the form you are designing, or because you are running the code.

    The control doesn't "own" much in the way of somewhere or somehow to store this information either. So what is needed is an interface onto a "loose" mechanism for storing and retreiving information, which it can then be stored by the owner of the control in a manner appropriate to it (for instance in the case of VB forms this information is used in combination with some information that is the form's business rather than the controls, such as the control's position, in the text that appears in the .frm file which isn't displayed in the VB IDE).

    PropertyBags offer this interface. When a control is created for the first time the InitProperties event fires, which enables it to set default properties. When it is "saved" the WriteProperties event is fired, and it is passed an empty PropertyBag which it can use to store properties. When it is instantiated again it gets a ReadProperties event with a PropertyBag that will appear to be the same as the one it wrote to previously (obviously it's not the same, but created out of whatever mechanism was used to store the information).

    Example. Say we have a control with a value property. This value is a Long.

    When the control is first created we are going to set the value to 101 for the simple reason that 101 isn't 0 and 0 is what we'd have if we didn't bother to do anything (and hence not much of an example):
    Private Sub UserControl_InitProperties()
    	Value = 101
    End Sub
    

    It might be more efficient to directly put 101 into whatever variable or whatever it is stored in, but there might be code in the Property Let procedure we want to have executed, so in general you shouldn't bypass such code.

    When the control is saved the WriteProperties control will be fired:
    Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
    	On Error Resume Next
    	'It's important no errors are raised!
    	With PropBag 'This With is more useful when there are many properties.
    		.WriteProperty "Value", Value, 101
    	End With
    End Sub
    

    In the call to writeproperty the name "Value" is associated with the result of the call to Value. 101 is a default, it is good to use a default of whatever value is most likely to be there. If Value is 101 then the call to .WriteProperty won't bother to record it, with an obvious space advantage.

    Finally when the control is instantiated again ReadProperties is fired:
    Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
    	On Error Resume Next
    	With PropBag
    		Value = .ReadProperty("Value", 101)
    		If Err.Number Then
    			Value = 101
    			Err.Clear
    		End If
    	End With
    End Sub
    

    Again we say the default value is 101, and we will use this value if WriteProperties saved space by ommitting this value (because it was 101).
    If an error occurs we do the best we can by using this default value. Again it is very important that an error doesn't get raised in a ReadProperties event, and also important that no matter what occurs Value has a valid value.

    Another reason for using PropertyBag is to make objects that aren't controls persistable. In this case we mark the object as persistable, and it will then have similar ReadProperties and WriteProperties events.

    Such a control can then be "saved" to another PropertyBag in the same way as a Long or String (it is by this mechanism that Controls can save their Font objects).

    PropertyBags have a Contents property which sets or returns an array of bytes. If we save a persistable control to a property bag we can then save this array of bytes somewhere (file, registry, database BLOB). Later we can read the array of bytes into another PropertyBag and "Read" of an object that will appear to be the same one we saved earlier.


  • Closed Accounts Posts: 5,564 ✭✭✭Typedef


    The propbag datatype essentially adds and reads properties from the ascii text of a .frm file for a given project, hence 'prop'bag.

    Then those properties are used later on by a control for example to do certain things, say make a label visible or invisible and so on, conducive with what you want control (x) to do.

    If you were to open up a .frm file in notepad and look at the various properties it sets, you might get a better idea of what I'm talking about.

    Note: VB still sucks.


  • Closed Accounts Posts: 5,564 ✭✭✭Typedef


    From some random activeX control.
    
    [b]m_kControlType = PropBag.ReadProperty("kControlType", m_def_kControlType)[/b]
    m_kRequired = PropBag.ReadProperty("kRequired", m_def_kRequired)
    m_kSqlString = PropBag.ReadProperty("kSqlString", m_def_kSqlString)
    
    

    someform.frm that has our active X component opened in notepad
    Begin KeyBank.uTextControl txARExec 
          Height          =   315
          Left            =   360
          TabIndex        =   10
          Top             =   3960
          Width           =   4095
          _ExtentX        =   7223
          _ExtentY        =   556
         [b] kControlType    =   1[/b]
          kLookupWidth    =   1100
          kSqlString      =   "luARExec"
          kLabelWidth     =   900
          kLabelCaption   =   "AR Exec"
          kLabelVisible   =   -1  'True
          BeginProperty Font {0BE35203-8F91-11CE-9DE3-00AA004BB851} 
             Name            =   "MS Sans Serif"
             Size            =   8.25
             Charset         =   0
             Weight          =   400
             Underline       =   0   'False
             Italic          =   0   'False
             Strikethrough   =   0   'False
          EndProperty
          Object.Width           =   4095
          Object.TabIndex        =   1
       End
    

    I hope that wasn't too clear and umambiguous, I'd hate to impart information : )


  • Closed Accounts Posts: 9,314 ✭✭✭Talliesin


    I hope that wasn't too clear and umambiguous, I'd hate to impart information : )
    Don't worry, there was still some ambiguity.
    While you are correct as to how a PropertyBag's information is stored when the control is on a VB form, that is not the only way that that information may be stored by whatever is using the control.
    However the author of the control (the person using the PropertyBag) doesn't need to know what mechanism is used, they have the same interface (the PropertyBag) whatever that mechanism might be.
    I could see a use for this if you had some complicated UI that users could customise and you wanted to revert to the users customised settings later after the application has been closed.
    It doesn't have to be even all that complicated to be useful. Consider the case where you put a textbox on a form and set MultiLine to True and change its Text. Without some means of persistance both those properties would change the moment you closed the design view of the form. The only alternative would be to set all of those in the Form_Load event.
    I only heard of property bags as someone was using it to store and transfer data between vb modules. Mainly data from a db as it happens. Why would you use it in that scenerio.

    Well if you have an object that is persistable then you can write it to a PropertyBag and then transfer those bytes elsewhere (to another module, to a db, to a file). When you get those bytes you can load it into another PropertyBag and create a clone of the original object from that.

    The main reason I would use this was because I had a control I wanted to save (the conventional use of a PropertyBag) and as part of doing so I wanted to write a persistable object (the built-in Font object would be an example of an object you can do this with).

    In other cases, I generally avoid the use of PropertyBag as a means to persist objects. It's pretty much unusable except by code written the same way, and I prefer to use XML or a conventional relational db structure to store information so that I'm not locked in too much as to one way to do something (as a general ideal one should be able to completely re-write any one piece of a system from scratch without necessitating changes to the rest, you shouldn't actually do that, but you should be able to).

    An example of where I have used such a technique is code which rendered various features of documents being editted in different ways. Because these features were not reflected by a WYSIWYG way it's up to the user's preferences as to which styles are used for which. When the user changed their preferences I wrote that information to a property bag, and then stored the resultant byte array in the registry (it's pretty compact - do not store large structures in the registry!), and read it again the next time the program is launched.


  • Closed Accounts Posts: 9,314 ✭✭✭Talliesin


    They have advantages though.

    They aren't that unorthodox a mechanism, they expose IPersist interfaces and as such from outside of VB look like any other persistable COM object. They are really just a VB way of doing something that doesn't work well with VB (direct manipulation of IPersist interfaces in VB is tricky to say the least).

    They are the only way of doing persistance with ActiveX Controls, and as such it is a vital piece of any VB coder's knowledge. Once you have mastered them you may come across situations where they are useful for other tasks.

    Like any tool they have their uses, but should not be used for every situation in which they could conceivably get the job done if another would work better.


  • Advertisement
Advertisement