title: Monitor class events from userform
body: <p>I have a userform which assembles itself at runtime, by looking in a folder and extracting all the pictures from it into image-controls on my form. What makes the process a little more complex is that I'm also using the image-controls' events to run some code.</p>
  
  <p>As a simplified example - I have a form which creates a picture at runtime, the picture has an on-click event to clear its contents. To do this I have a custom class to represent the image object</p>
  
  <p>In a blank userform called "imgForm"</p>
  
  <pre><code>Dim oneImg As New clsImg 'our custom class
  
  Private Sub UserForm_Initialize()
  Set oneImg.myPic = Me.Controls.Add("Forms.Image.1") 'set some property of the class
  oneImg.Init 'run some setup macro of the class
  End Sub
  </code></pre>
  
  <p>In a class module called "clsImg"</p>
  
  <pre><code>Public WithEvents myPic As MSForms.Image
  
  Public Sub Init() 'can't put in Class_Initialise as it is called before the set statement - so myPic is still empty at that point
  myPic.Picture = LoadPicture(path/image)
  End Sub
  
  Public Sub myPic_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
  onePic.Picture = Nothing
  End Sub
  </code></pre>
  
  <p><strong>The problem is, this doesn't display the changes,</strong> and I realised I needed a <code>imgForm.Repaint</code> in there somewhere - <strong>the question is, where?</strong></p>
  
  <h2><em>Attempts</em></h2>
  
  <p>First option is to put it in the <code>Init()</code> sub of <code>clsImg</code>. (ie. have a line <code>imgForm.Repaint</code> at the end of the click event) That works, but not ideal as the class can then only be used with the userform of the correct name.</p>
  
  <hr>
  
  <p>A 2nd idea was to pass the userform as an argument to <code>Init()</code></p>
  
  <pre><code>Public Sub Init(uf As UserForm) 'can't put in Class_Initialise as it is called before the set statement - so myPic is still empty at that point
  myPic.Picture = LoadPicture(path/image)
  uf.Repaint
  End Sub
  </code></pre>
  
  <p>And called with</p>
  
  <pre><code>oneImg.Init Me
  </code></pre>
  
  <p>That works too, but would mean that wherever I require a repaint, I would have to pass the parameter which is also not ideal - the code is in reality a lot more complex than is shown here, so I don't want to have to add in this extra parameter unless necessary</p>
  
  <hr>
  
  <p>The third option which I'm currently using is to pass the userform object to the class and save it there.</p>
  
  <p>So with a <code>Public myForm As UserForm</code> at the top of my class module, I can pass the userform with the <code>Init(uf As UserForm)</code> and have a </p>
  
  <pre><code>Set myForm = uf 'Works with a private "myForm"/ class Property
  </code></pre>
  
  <p>Or I can set it directly from the userform code with a </p>
  
  <pre><code>Set clsImg.myForm = Me 'only if "myForm" is Public
  </code></pre>
  
  <p>But what does this do for memory - does saving the userform as a variable in my class take up a lot of memory? Bear in mind that in my real code I declare an array of <code>clsImg</code>s that can be of the order of >100 instances so I don't really want to be making copies of the UF in <em>each class</em> if that's what this method does. Also, it's ugly</p>
  
  <h1>What I really want...</h1>
  
  <p>... is a way of <em>telling</em> the userform that it needs to repaint, rather than directly repainting from within the class. To me this says I need an event to occur in my class, which the userform <em>hears</em> with some custom event handler. Exactly how Worksheet_Change works, the sheet object raises a change event, the sheet class code handles it.</p>
  
  <p>Is such a thing possible (I suppose I would have to declare <code>clsImg WithEvents</code> - can you do that for an array?), or is there a better alternative. I'm looking for a method which does not impede performance with a large number of classes declared, as well as one which is portable and easily readable. This is my first use of Classes so I may be missing something really obvious!</p>