.Net class library and windows application projects

Fuma

Executive Member
Joined
Jul 9, 2007
Messages
5,111
I have a windows application project which has a form (frmGUI) with a label control (Label1) and a button. When i click the button, it will call the doStuff's doLoop function and display the i value in frmGUI.Label1.Text (the line in bold). Is that possible

Code:
Imports Test

Public Class frmGUI

    Private Sub btnGo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGo.Click
        [COLOR="Green"]'call the testStuff.doLoop("value")[/COLOR]

    End Sub

End Class

I also have a class library project called Test with the following class:

Code:
Public Class doStuff

  Public Function doLoop(ByVal db As String)
  
    For i = 0 To 10  
      [B]frmGUI.Label1.Text = i[/B]
    Next i
    
    Return Nothing
  End Function

End Class

Edit: I can't seem to indent my quotes.
 
Last edited:

hsmnel

Senior Member
Joined
Jul 13, 2005
Messages
714
add Application.DoEvents() before the line "Next i" to give GIU time to update.
 

Saajid

Expert Member
Joined
Aug 8, 2008
Messages
4,559
Ahhh.. my eyes! VB!! Ahhh!

OK.. now for some useful info - post your question on StackOverflow.com.

It's a Q&A site for developers / programmers / software engineers etc. It's the biggest and the best in the world.

You can register for free, using an OpenID supported email account (like GMail, for example).
 

dequadin

Expert Member
Joined
May 9, 2008
Messages
1,434
Put you code in [ code ] [ /code] blocks to see your indents.

You can do what you want, but it's not ideal. What you need to do is pass the instance of the form through to the class library. Either via the constructor OR in the method you are calling. I don't like this method of doing things except in the case of dialog boxes, but that's a different argument.

Try this:
Code:
Imports Test
Public Class frmGUI
    Private Sub btnGo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGo.Click
        testStuff.doLoop("value", Me)
    End Sub
End Class

Imports System.Windows.Forms
Imports System.Threading
Imports Namespace.Where.frmGUI.Is.Declared
Public Class doStuff
    Public Function doLoop(ByVal db As String, ByVal formToUpdate AS frmGUI)
        For i = 0 To 10 
            formToUpdate.Label1.Text = i.ToString
            Thread.Sleep(500) 'Give it time to update otherwise you'll only see the last value
        Next i
        Return Nothing
    End Function
End Class

EDIT: You should rather have you class library return a value and then update the form in it's own class.

Something like:
Code:
Me.Label1.Text = testStuff.doLoop("value")
 

Fuma

Executive Member
Joined
Jul 9, 2007
Messages
5,111
The frmGUI is in the prjFrontEnd project.
I had to create an exe for prjFrontEnd and added it as a reference, and by default a class library doesn't have System.Windows.Forms by default. So I had to add it as well.
I tried:
Code:
Imports prjFrontEnd  
Imports System.Windows.Forms

Public Class doStuff

  Public Function doLoop(ByVal db As String)
    dim frmGUILabel as frmGUI = new frmGUI
    For i = 0 To 10 
      frmGUILabel.[B]Label1.Text [/B]= i
      Application.DoEvents()
    Next i

  Return Nothing
End Function

End Class

It doesn't seem to find Label1
 
Last edited:

dequadin

Expert Member
Joined
May 9, 2008
Messages
1,434
The frmGUI is in the prjFrontEnd project.
I had to create an exe for prjFrontEnd and added it as a reference, and by default a class library doesn't have System.Windows.Forms by default. So I had to add it as well.
That's normal...
It doesn't seem to find Label1

You need to make it Public. In the form designer check the properties in the Label1. In the property panel Design->Modifiers.

Dimming a new form will not help you as you want to update the existing form? That's why you need to pass it as a parameter...
 

Fuma

Executive Member
Joined
Jul 9, 2007
Messages
5,111
That's normal...


You need to make it Public. In the form designer check the properties in the Label1. In the property panel Design->Modifiers.
Thank you. I'm such a noob.

Dimming a new form will not help you as you want to update the existing form? That's why you need to pass it as a parameter...

When I call testStuff.doLoop("value", Me), it says "Value of type 'prjFrontEnd.frmGUI' cannot be converted to 'prjFrontEnd.frmGUI'
 

dequadin

Expert Member
Joined
May 9, 2008
Messages
1,434
When I call testStuff.doLoop("value", Me), it says "Value of type 'prjFrontEnd.frmGUI' cannot be converted to 'prjFrontEnd.frmGUI'

That's weird, this complies fine for me:
Code:
Public Class Class1
    Public Sub DoIt(ByVal Form As mainForm)
    End Sub
End Class

Public Partial Class mainForm
    Inherits Form
 
    Public Sub New()
        InitializeComponent()

        Dim c1 As New Class1()
        c1.DoIt(Me)
    End Sub
End Class

EDIT: It seems you are having some sort of referencing issue. Are you using project references or file references? Check out this thread
 
Last edited:

Fuma

Executive Member
Joined
Jul 9, 2007
Messages
5,111
I tried using both project and file references, and still.
 
Last edited:

guest2013-1

guest
Joined
Aug 22, 2003
Messages
19,800
Hmmm, what dequadin suggested should work fine.

What i suggest you do is create a new project file and run his code in there, check how it works, and then try and apply it to your own project.

That's what I usually do, and it's easier to see where you can go wrong. The error message you get basically means that you're doLoop function is expecting something and you're sending it something else, so the "cast" fails.
 

dequadin

Expert Member
Joined
May 9, 2008
Messages
1,434
I tried using both project and file references, and still.

I just realised something here. You have two separate projects? One Class Library project and one Windows Forms project?

If that's the case you cannot do this. Because you need to reference the WinForms project from the Class library (to pass the form instance) and you need to reference the Class library from the WinForms project (to call the method). This is not allowed, two projects cannot reference eachother.

Can't you add the class to your WinForms project and then use it there (this will work fine).
 

Fuma

Executive Member
Joined
Jul 9, 2007
Messages
5,111
I just realised something here. You have two separate projects? One Class Library project and one Windows Forms project?

If that's the case you cannot do this. Because you need to reference the WinForms project from the Class library (to pass the form instance) and you need to reference the Class library from the WinForms project (to call the method). This is not allowed, two projects cannot reference eachother.

Can't you add the class to your WinForms project and then use it there (this will work fine).

I wish I could add the class to my WinForms project, but we grouped everything accordingly. Some of the projects have a solution that has about 5 different class library projects grouped according to what they do (xml, db, emails, console, http stuff). So I can't just move that class.

So basically I have a label in one of the forms that must display what the doLoop (as per example) is busy with, coz at the moment, the form just stays there looking like nothing is happaning whereas that doLoop is processing like 500 records per i (there are about 1000 i's). Unless I can use another method to to display what the current i is. Any ideas?
 

dequadin

Expert Member
Joined
May 9, 2008
Messages
1,434
I wish I could add the class to my WinForms project, but we grouped everything accordingly. Some of the projects have a solution that has about 5 different class library projects grouped according to what they do (xml, db, emails, console, http stuff). So I can't just move that class.

So basically I have a label in one of the forms that must display what the doLoop (as per example) is busy with, coz at the moment, the form just stays there looking like nothing is happaning whereas that doLoop is processing like 500 records per i (there are about 1000 i's). Unless I can use another method to to display what the current i is. Any ideas?

Okay, my suggestion is to then have your class library expose an event. Then I would subscribe to this event from the form you need to update. You can then raise this event every iteration (or maybe every 5 iterations of it's processing really quickly) of your loop, and update the form that way.

This is how BackgroundWorker handles this scenario, with the ProgressChanged Event.
 

guest2013-1

guest
Joined
Aug 22, 2003
Messages
19,800
Try what dequadin said earlier. Let the doLoop return a value (i or whatever) and show it within the WinForms project.
 

FarligOpptreden

Executive Member
Joined
Mar 5, 2007
Messages
5,396
Have you tried passing the Label through to the doLoop method by reference and update it like that? That way you can still have them in different projects, with only the WinForms project referencing the Class Library project... You will only need to include the System.Windows.Forms namespace to your Class Library...
 

dequadin

Expert Member
Joined
May 9, 2008
Messages
1,434
Have you tried passing the Label through to the doLoop method by reference and update it like that? That way you can still have them in different projects, with only the WinForms project referencing the Class Library project... You will only need to include the System.Windows.Forms namespace to your Class Library...

+1 OMG such a simple solution :)

Label is a reference type so you can still update the .Text property without having to pass it by reference, so I wouldn't do that.
 

Fuma

Executive Member
Joined
Jul 9, 2007
Messages
5,111
Okay, my suggestion is to then have your class library expose an event. Then I would subscribe to this event from the form you need to update. You can then raise this event every iteration (or maybe every 5 iterations of it's processing really quickly) of your loop, and update the form that way.

This is how BackgroundWorker handles this scenario, with the ProgressChanged Event.

You are talking jargon now. LOL. I'm a noob.
By example is way better.
 
Top