Hello,

I have two projects in this solution: ProjectA and ProjectB. ProjectA is the main start-up project, and has a reference to ProjectB.

ProjectA has a file called MainForm.cs, which contains a textbox and the main UI.

ProjectB has a class inside Shapes.cs, containing a particular structure we're using. Shapes.cs contains an event that is fired when the user changes some text for that object.

What I need to do is catch that text and set a textbox in MainForm.cs to that text. Is there a way we can do that? Basically I don't see any reference to the main form inside Shapes.cs. I would like to do something like this:

( Shape1.Parent as MainForm ).TextBox1.Text = Shape1.Name;

, assuming the user types a string that gets stored in Shape1.Name. I need to escalate it to the main form.

Thanks.

You have to add a reference of the project you want to access to (right click on References in solution explorer, then select Add Reference, then select Browse tab and look for appropriate file in the project you want to access).
Then Add this reference on the top on the class you want to access from (using YourProjectname).
Then you should see the pulbic members of the class you access.

Thanks for the advice, but it won't let me select the file. The Browse for files only filters files of type: "Component Files (*.dll; *.tlb; *.olb; *.ocx; *.exe; *.manifest)."
Am I supposed to look for MainForm.cs?

It won't let me. It says,

---------------------------
Microsoft Visual Studio
---------------------------
A reference to 'D:\Projects\Diagrams\Diagrams\MainForm.cs' could not be added. Please make sure that the file is accessible, and that it is a valid assembly or COM component.
---------------------------
OK   
---------------------------

This is what you have to do exactly:

1.
The first step is to make P2 reference P1 by doing the following:

Right Click on the project and select "Add Reference";
Go to the Projects Tab (or Browse Tab);
Look for P1, Select it and hit OK;

2.
Next you'll need to make sure that the classes in P1 are accessible to P2. The easiest way is to make them public:

public class MyType { ... }

3.
Now you should be able to use them in P2 via their fully qualified name.
Assuming the namespace of P1 is Project1 then the following would work:

Project1.MyType obj = new Project1.MyType();

4.
The preferred way though is to add a using for Project1 so you can use the types without qualification:

using Project1;
...

public void Example()
{
MyType obj = new MyType();
}

Thank you for the clear steps. Makes sense, but VS won't let me, since P1 (the start-up project) already references P2. It says,

---------------------------
Microsoft Visual Studio
---------------------------
A reference to 'Diagrams' could not be added. Adding this project as a reference would cause a circular dependency.
---------------------------
OK   
---------------------------

Edited 4 Years Ago by SoftwareGuy: n/a

You can only reference in one way otherwise you get the error like you said. Just do this: delete the reference from your DAL to your BL and make a new one from your BL to your DAL!

I'm sorry I'm still a beginner at this. What are "DAL" and "BL?"

never mind, do it this way:

//assembly 1:
namespace Mar14_Part1
{
    class Program
    {
        static void Main(string[] args)
        {
        }
    }

    public class MyClass
    {
        public string MyMethod()
        {
            return " some text from other assembly";
        }
    }
}

//assembly 2:
//add reference of assemby1 like I told you on top
then do:
using Mar14_Part1;

namespace Mar14_Part2
{
    class Program
    {
        static void Main(string[] args)
        {
            MyClass mc = new MyClass();
            string str = mc.MyMethod();
            Console.WriteLine(str);
            Console.ReadLine();
        }
    }
}

Mine example works!

I got this example. I think I should be able to apply it to my app. Thanks for your help.

OK, you found a solution, but nobody suggested a delagate. I tried to build a puzzle solving code and display intermediate results and display them on my WinApp form. Didn't do a thing. Turns out, the form thread has to be idle to display changes and I wanted intermediate results not the final ones.

Now the puzzle solving app (PA) is completely separate from my form, so it can be run for any kind of UI. My form subscribes to the delegate and if it asks the PA to show intermediate results, the PA calls the delegate passing a byte array and a text array and then sleeps for the length of time the form asks for. (The PA will allow sleeping for an hour, the form will only ask to sleep up to 10 seconds.) The form wakes up moves the bytes and strings into text boxes and then exits. (Letting the form to sleep again. The sleep refreshes the text box displays.)

Comments
Thank you for adding insight and an alternative to a problem, even after the thread was closed.

Thanks for the input, kplcjl. My boss did not agree that I do it the first way and had me do it with EventHandlers.

Inside the main sub-class event he had me call this:

public event EventHandler ShapeValueChanged;
if (ShapeValueChanged != null) 
    ShapeValueChanged(this, new EventArgs());

and then in the main form:

ShapeValueChanged += new EventHandler(Form1_ShapeValueChanged);

Thank you both for your help and precious advice.

EventHandlers are one form of a delegate.
ShapeValueChanged is the delegate.

The following is the subscription of the delegate to the Form1_ShapeValueChanged method:
ShapeValueChanged += new EventHandler(Form1_ShapeValueChanged);

The forms detects an event change and calls the event handler ShapeValueChanged which calls all the subscriptions to it. In this case, only one subscription.

Awesome. Thanks a lot for the clarification. I really appreciate you spending the time giving further information.

Actually, I misread what you had. Your second class IS the event handler, your form subscribes to the event delegate and at the same time makes it not null in your class so it can pass the event back to the form.

This question has already been answered. Start a new discussion instead.