none
Setting image value from form to user control RRS feed

  • Question

  • I have a Usercontrol which contains a picturebox. On the same user control a buttons shows a form which also contains a picturebox. upon closing the form I want to transfer the picture from the form's picturebox to the usercontrol's picturebox.

    I've imported the usercontrol namespace on the form, and when I try setting the image I get "Reference to a non-shared member requires an object reference"

            pb_part.Image = pb_cropimg.Image
            Close()

    I have also tried to expose the property from the usercontrol and set the property from the form, but I get the same error

    'user control'
        Public WriteOnly Property PartImg As Image
            Set(value As Image)
                pb_part.Image = value
            End Set
        End Property
    
    'form'
    PartImg = pb_cropimg.Image

    Am I even close? seems like I am missing something simple.


    Live as if you were going to die today, learn as if you were going to live forever -Mahatma Gandhi

    Tuesday, February 21, 2017 3:28 AM

Answers

  • Hey bud,

    On your crop form, add a parameter to the constructor so that you can pass the instance of the UserControl to the Form.  Capture that reference into a form variable and you should be good to go.

    Pseudo code example:

    Public Class CropForm
       Private sourceControl As UserControltypename
       Public Sub New(theControl As UserControltypename)
          sourceControl = theControl
       End Sub
    
       Private Sub Form_Closing(sender as object, e as eventargs) handles Me.Closing
          sourceControl.Picture = me.Picture
       End Sub
    End Class
    Public Class UserControltypename
       Inherits UserControl
    
       Sub ShowCropForm()
          using f As New CropForm(Me)
          f.Show()
       End Sub
    End Class


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    • Marked as answer by Gtripodi Tuesday, February 21, 2017 3:50 PM
    Tuesday, February 21, 2017 12:52 PM
    Moderator
  • Reed! it's great to see you're still around. I have literally circled the globe in the past few months, looking more for questions than answers if you can understand that one. I blew my budget, however, and unfortunately I can't just keep traveling like I am Bill Gates. There is still this reality thing calling me back to work.

    So, back to the topic at hand, I only 1/2 way follow you. Right now I use a button to show a form that captures a picture and inserts it into a large picturebox where you can draw a square and crop the image as desired, which then plops the cropped image into a smaller picturebox on the crop form. Then there is a button to hopefully put this cropped image in the picture box on the already open user control. It looks to me that the ShowCropForm Sub you have supplied would go on this button and the class's should be within the CropForm form?

    Currently I open the CaptureForm like so (from a button on the user control)

        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim CapForm As New CapturePhoto
            CapForm.Show()
        End Sub

     

    Live as if you were going to die today, learn as if you were going to live forever -Mahatma Gandhi

    Sounds like it was an exciting adventure. :)

    I think we are headed for the same page here...

    If I've followed you correctly, your CapturePhoto form should have the constructor which takes a reference to the user control like the "CropForm" in my example.  Your button1 click code would then pass the reference to the usercontrol when you create the form instance.

        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim CapForm As New CapturePhoto(Me)
            CapForm.Show()
        End Sub

    Following the example code, the picturebox on the usercontrol would be updated to the image in the picturebox on CapForm when CapForm closes.

    Does that sound right?


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    • Marked as answer by Gtripodi Tuesday, February 21, 2017 3:19 PM
    Tuesday, February 21, 2017 1:59 PM
    Moderator
  • Ah, sorry, don't copy-paste a sub new in a Form.  Type Sub new and hit enter - the designer will throw in some boilerplate code to call InitializeComponents in the constructor.  That's likely all that's gone wrong.

        Public Sub New(theControl As PartManager)
            Me.InitializeComponents
            sourceControl = theControl
        End Sub
    


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    • Marked as answer by Gtripodi Tuesday, February 21, 2017 3:19 PM
    Tuesday, February 21, 2017 3:09 PM
    Moderator

All replies

  • I've imported the usercontrol namespace on the form, and when I try setting the image I get "Reference to a non-shared member requires an object reference"

    To reference a control on another form you need a reference to an actual instance of the form or the control.  That's the 'object reference' in the message.  See here for several ways to pass a reference from one form to another.  The constructor (2) is the best way to do it, because that guarantees that it exists.

    Tuesday, February 21, 2017 3:43 AM
  • Thanks for the reply Acamar.

    I believe that (2) creates a new instance of the form (or user control) and does work as you would expect, but I need to get the image back to the calling user control, number (4) looks more applicable, but I am either not understanding, or you cant pass an image this way.


    Live as if you were going to die today, learn as if you were going to live forever -Mahatma Gandhi

    Tuesday, February 21, 2017 6:03 AM
  • Hey bud,

    On your crop form, add a parameter to the constructor so that you can pass the instance of the UserControl to the Form.  Capture that reference into a form variable and you should be good to go.

    Pseudo code example:

    Public Class CropForm
       Private sourceControl As UserControltypename
       Public Sub New(theControl As UserControltypename)
          sourceControl = theControl
       End Sub
    
       Private Sub Form_Closing(sender as object, e as eventargs) handles Me.Closing
          sourceControl.Picture = me.Picture
       End Sub
    End Class
    Public Class UserControltypename
       Inherits UserControl
    
       Sub ShowCropForm()
          using f As New CropForm(Me)
          f.Show()
       End Sub
    End Class


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    • Marked as answer by Gtripodi Tuesday, February 21, 2017 3:50 PM
    Tuesday, February 21, 2017 12:52 PM
    Moderator
  • Reed! it's great to see you're still around. I have literally circled the globe in the past few months, looking more for questions than answers if you can understand that one. I blew my budget, however, and unfortunately I can't just keep traveling like I am Bill Gates. There is still this reality thing calling me back to work.

    So, back to the topic at hand, I only 1/2 way follow you. Right now I use a button to show a form that captures a picture and inserts it into a large picturebox where you can draw a square and crop the image as desired, which then plops the cropped image into a smaller picturebox on the crop form. Then there is a button to hopefully put this cropped image in the picture box on the already open user control. It looks to me that the ShowCropForm Sub you have supplied would go on this button and the class's should be within the CropForm form?

    Currently I open the CaptureForm like so (from a button on the user control)

        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim CapForm As New CapturePhoto
            CapForm.Show()
        End Sub

     

    Live as if you were going to die today, learn as if you were going to live forever -Mahatma Gandhi

    Tuesday, February 21, 2017 1:39 PM
  • Reed! it's great to see you're still around. I have literally circled the globe in the past few months, looking more for questions than answers if you can understand that one. I blew my budget, however, and unfortunately I can't just keep traveling like I am Bill Gates. There is still this reality thing calling me back to work.

    So, back to the topic at hand, I only 1/2 way follow you. Right now I use a button to show a form that captures a picture and inserts it into a large picturebox where you can draw a square and crop the image as desired, which then plops the cropped image into a smaller picturebox on the crop form. Then there is a button to hopefully put this cropped image in the picture box on the already open user control. It looks to me that the ShowCropForm Sub you have supplied would go on this button and the class's should be within the CropForm form?

    Currently I open the CaptureForm like so (from a button on the user control)

        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim CapForm As New CapturePhoto
            CapForm.Show()
        End Sub

     

    Live as if you were going to die today, learn as if you were going to live forever -Mahatma Gandhi

    Sounds like it was an exciting adventure. :)

    I think we are headed for the same page here...

    If I've followed you correctly, your CapturePhoto form should have the constructor which takes a reference to the user control like the "CropForm" in my example.  Your button1 click code would then pass the reference to the usercontrol when you create the form instance.

        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim CapForm As New CapturePhoto(Me)
            CapForm.Show()
        End Sub

    Following the example code, the picturebox on the usercontrol would be updated to the image in the picturebox on CapForm when CapForm closes.

    Does that sound right?


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    • Marked as answer by Gtripodi Tuesday, February 21, 2017 3:19 PM
    Tuesday, February 21, 2017 1:59 PM
    Moderator
  • I am figuring I botched something while adopting your solution. It compiles okay, but other things are breaking on the CaptureForm, specifically a method in which loads capture devices into an array on the form load. I am receiving the classic "Object reference not set to an instance of an object" once I try to pen the CaptureForm

    'CaptureForm'
    Public Class CapturePhoto
    
        Private sourceControl As PartManager
        Public Sub New(theControl As PartManager)
            sourceControl = theControl
        End Sub
    
        Private Sub Form_Closing(sender As Object, e As EventArgs) Handles Me.Closing
            sourceControl.pb_part.Image = Me.pb_capimg.Image
        End Sub
    
        Dim myimg As Image
        Dim cropX As Integer
        Dim cropY As Integer
        Dim cropWidth As Integer
        Dim cropHeight As Integer
    
        Dim oCropX As Integer
        Dim oCropY As Integer
        Dim cropBitmap As Bitmap
    
        Public cropPen As Pen
        Public cropPenSize As Integer = 1 '2
        Public cropDashStyle As Drawing2D.DashStyle = Drawing2D.DashStyle.Solid
        Public cropPenColor As Color = Color.Red
    
        Private Sub CapturePhoto_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Me.Width = 389
            Dim cams As New List(Of WebCameraId)(CamCtrl.GetVideoCaptureDevices())
            ListBox1.Items.Clear()
            For Each itm As WebCameraId In cams
                ListBox1.Items.Add(itm.Name.ToString)
            Next
            CamCtrl.StartCapture(cams(0))
        End Sub

    'calling user control'
    Public Class PartManager
        Inherits UserControl
    
       
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim CapForm As New CapturePhoto(Me)
            CapForm.Show()
        End Sub
    End Class

     

    Live as if you were going to die today, learn as if you were going to live forever -Mahatma Gandhi


    • Edited by Gtripodi Tuesday, February 21, 2017 3:06 PM
    Tuesday, February 21, 2017 3:06 PM
  • Ah, sorry, don't copy-paste a sub new in a Form.  Type Sub new and hit enter - the designer will throw in some boilerplate code to call InitializeComponents in the constructor.  That's likely all that's gone wrong.

        Public Sub New(theControl As PartManager)
            Me.InitializeComponents
            sourceControl = theControl
        End Sub
    


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    • Marked as answer by Gtripodi Tuesday, February 21, 2017 3:19 PM
    Tuesday, February 21, 2017 3:09 PM
    Moderator
  • Gtripodi,

    Try to understand that .Net is working with references. 

    You seldom copies something. One of the situation you do that is if you crop an image, but that is not the case in this code. 

    If you do 

       pb_part.Image = pb_cropimg.Image

    You only tell that there is somewhere an address (also sometimes named Delegate or just Reference) copied. 

    The image itself stays the same image. 

    Therefore if you want to use that image on another place is the only thing you have to do to give the right address on that place. 

    Another thing you have to know that an object (that is an instanced class) has a certain lifetime. If something goes out of scope and is not used anymore on another place the garbage collector released at a time which is the most optimized moment for that. 

    Therefore what has to be done is that if you instance the usercontrol (that happens with the constructor which is that famous New keyword), you can do it without referencing that image or with it, that is called overloading the constructor, so for instance

    Sub New(TheImageToUse as image) 'with passing the address

    and 

    Sub New() 'without passing the address


    Success
    Cor


    Tuesday, February 21, 2017 3:19 PM
  • Perfect! You're the man Reed. <3

    Live as if you were going to die today, learn as if you were going to live forever -Mahatma Gandhi

    Tuesday, February 21, 2017 3:20 PM
  • I believe that (2) creates a new instance of the form (or user control) and does work as you would expect, but I need to get the image back to the calling user control, number (4) looks more applicable, but I am either not understanding, or you cant pass an image this way.

    If the form that you are opening has a reference to the user control contained in the calling form, or to the calling form itself, then your code in the form you are opening can use that reference to update a property (eg, Picturebox1.image) at any time. I am not proposing that you pass the image from the calling form to the form being opened - I am proposing that you pass a reference to the control (or to itself), so that the form that you are opening can do the update to the user control as required, using that reference.

    Wednesday, February 22, 2017 12:28 AM