VB.NET中实现不同窗体间控件的访问

Multiple Forms in VB.NET. Part 1

Article source code: multipleforms.zip

_________________________________

Authors' Note February 2006:

This article was written inJune 2003andwas aimed at users of the VB.NET 2002 and 2003 editions who were upgrading from VB6. Now that VB2005 has arrived, much of the content has been overtaken by improvements in that new edition and won't be applicable if this is the version you are using.

________________________________

Introduction

One of the first hurdles you're going to come up against when you move from Classic VB to VB.NET is getting to grips with the new ways of dealing with forms.

Your approach to forms in VB.NET is fundamentally different and hinges on the fact that the Framework implements forms as classes, so now you need an object variable to instantiate it. This article is aimed at helping you through some of those basic steps.

Instead of loading and showing a form in the old way (eg. Form2.Show, what you have to do is create an instance of the form and you can then manipulate this form object.

Method 1: Show More Than One Instance of a Second Form

Here's one way. Let's assume that you have a project that contains a Form1 and a Form2. You have already set Form1 to be the startup form and it contains a button which, when clicked, will display an instance of Form2 to the user. Assuming this button is called ShowForm2Button, the code you need is as follows:

<!-- Generated using PrettyCode.Encoder at http://www.vbcity.com/encoder --><!-- PrettyCode.Encoder Copyright (c) 2000 vbCity.com --><!-- START http://www.vbcity.com/encoder -->




<!-- END http://www.vbcity.com/encoder -->

If you try this code out, you'll find that it works fine, as far as it goes. But you will also discover that it is possible to have several instances of Form2 displayed at the same time if you click the ShowForm2Button before you have closed down the current instance of Form2. Each click of the button does exactly what the code tells it to do - create a new instance of a Form2 Class object and show it.

Of course, this may not be what you need in your project. You may want to have only a single instance available at any one time.

This can be achieved in several ways. Each has advantages and disadvantages, and some may yield unexpected results to the OOP-unwary developer. The following way might be an acceptable fix for you in many situations:

Method 2: Show Second Form Modally

There is a potentially easy way round the problem. Show the second form modally (a concept you'll be familiar with from VB.OLD, I'm sure). The .NET syntax is:-

<!-- Generated using PrettyCode.Encoder at http://www.vbcity.com/encoder --><!-- PrettyCode.Encoder Copyright (c) 2000 vbCity.com --><!-- START http://www.vbcity.com/encoder -->




<!-- END http://www.vbcity.com/encoder -->

Now, as you'd expect, the user can't get focus back to Form1 to click that pesky button again until they've closed down this instance of Form2.

However, there will probably be times when you want the best of both worlds, that is you want the user to only have one instance of your second form instantiated at any one time, but you want them to be able to see and use both Form1 and Form2 at the same time.

The solutions for showing forms in this way are easy. Where the problems start to kick in are that you may get side effects that are not so welcome if you don't take steps to deal with them.

Method 3: Allow Only One Instance of Second Form.

Type this into the main body of the form (i.e. outside any Subs, Events or Methods)

<!-- Generated using PrettyCode.Encoder at http://www.vbcity.com/encoder --><!-- PrettyCode.Encoder Copyright (c) 2000 vbCity.com --><!-- START http://www.vbcity.com/encoder -->
 
<!-- END http://www.vbcity.com/encoder -->

And use this code in the button's click event:

<!-- Generated using PrettyCode.Encoder at http://www.vbcity.com/encoder --><!-- PrettyCode.Encoder Copyright (c) 2000 vbCity.com --><!-- START http://www.vbcity.com/encoder -->





<!-- END http://www.vbcity.com/encoder -->

As promised, this will only show the single instance of Form2, because it isn't instantiated afresh every time you click the button. That's the up side.

The down side is that if you close Form2, then try and display it again by clicking on the button you will generate an exception.

The error message tells you why - you instantiated the Form2 object when Form1 was first created and you disposed of it when you closed it by clicking on the little x.

Trying to show it again will not succeed now because clicking on the button doesn't actually create another instance - it's simply trying to show a non-existent instance.

Let's find a couple of workarounds for this little glitch.

Method 4: Showing/Hiding a Second Form.

Instead of closing Form2, why don't we simply hide it? In many situations this may be an acceptable solution.

The code for Form1 is the same as for the above method. Your Form2 will need to be rigged so that it hides itself. Here's the easiest way:

  1. Change Form2's ControlBox Property to False. (This removes the ability of the user to close this form by using the little x).
  2. Add a button to Form2. Call this button FinishedButton.
  3. Use the following code in the button's click event:
<!-- Generated using PrettyCode.Encoder at http://www.vbcity.com/encoder --><!-- PrettyCode.Encoder Copyright (c) 2000 vbCity.com --><!-- START http://www.vbcity.com/encoder -->



<!-- END http://www.vbcity.com/encoder -->

What we've done here is to create a situation where there is only one instance of Form2 and this instance is shown when the ShowForm2Button is clicked and hidden when the FinishedButton is clicked. The user is no wiser as to whether a form is closed or hidden.

So, does this solve all possible requirements? Of course not - this is programming; there's always another problematic scenario just around the corner!

Method 5: Showing/Hiding a Second Form (Alternative)

What if you need to allow the user to have access to the Minimize or Maximize buttons in the ControlBox? As far as I know, although you can disable them, you can't have just these two buttons visible without also showing the exit button.

My fix for this involves cutting out the middleman. If there has to be a ControlBox and it has to contain the little x, then let's short circuit that little x. Here's how:

Leave Form2 with it's ControlBox available and dispense with the FinishedButton. What we'll do is change the code that gets fired when the user clicks on that little x. This is the form's Closing event. Add this code to Form2.

<!-- Generated using PrettyCode.Encoder at http://www.vbcity.com/encoder --><!-- PrettyCode.Encoder Copyright (c) 2000 vbCity.com --><!-- START http://www.vbcity.com/encoder -->






<!-- END http://www.vbcity.com/encoder -->

Be aware of a not so obvious knock-on effect here, though, if Form1 is not the startup form for your application. In this situation, when you close Form1 it will NOT automatically close Form2 (which is what always happens if Form1 is the startup form). So, something to keep in mind there - if you're happy to have Form2 still open once Form1 has closed, then that's fine; if not, then add this code to Form1's Closing event:

<!-- Generated using PrettyCode.Encoder at http://www.vbcity.com/encoder --><!-- PrettyCode.Encoder Copyright (c) 2000 vbCity.com --><!-- START http://www.vbcity.com/encoder -->
 
<!-- END http://www.vbcity.com/encoder -->

And it will take Form2 away with it when it closes.

Method 6: Check Current Status First

There is another way. Well, there's almost always another way, isn't there? This is based very closely on code provided by DevCity.NET member DrDave. It steps through a checklist of the possible states of the second form and takes the appropriate action depending on what it finds.

I've tried to make the steps as clear as possible with the commenting, but if you're like me you'll probably have to read it and try it a few times before it all clicks into place.

Here's the code:

Declaration outside of any methods:

<!-- Generated using PrettyCode.Encoder at http://www.vbcity.com/encoder --><!-- PrettyCode.Encoder Copyright (c) 2000 vbCity.com --><!-- START http://www.vbcity.com/encoder -->
 
<!-- END http://www.vbcity.com/encoder -->

And this code goes in the button's click event:

<!-- Generated using PrettyCode.Encoder at http://www.vbcity.com/encoder --><!-- PrettyCode.Encoder Copyright (c) 2000 vbCity.com --><!-- START http://www.vbcity.com/encoder -->























<!-- END http://www.vbcity.com/encoder -->

Method 7: Flip-Flop Form1 and Form2

Another possible scenario might be where you need Form1 hidden while Form2 is on view, and for Form1 to be redisplayed when Form2 is closed.

This gets a bit more complicated, but only a bit. In the same way that we needed an object variable to reference our Form2s in the examples above, we will need a reference back to the instance of Form1 which we can use in Form2.

There are various ways of doing this, but we're going to overload the Form's constructor to achieve our aim. Less technically, this simply means that we'll create an alternative version of the 'New' Sub that all forms contain. This one will make a note of which form called it into existence.

Starting with Form1, add this code to the form:

<!-- Generated using PrettyCode.Encoder at http://www.vbcity.com/encoder --><!-- PrettyCode.Encoder Copyright (c) 2000 vbCity.com --><!-- START http://www.vbcity.com/encoder -->






<!-- END http://www.vbcity.com/encoder -->

Don't worry if you get a wiggly blue line error at this stage in Form1's code. The next bit of code in Form2 will resolve that. Form2 needs this code:

Add an additional Sub New:

<!-- Generated using PrettyCode.Encoder at http://www.vbcity.com/encoder --><!-- PrettyCode.Encoder Copyright (c) 2000 vbCity.com --><!-- START http://www.vbcity.com/encoder -->





<!-- END http://www.vbcity.com/encoder -->

Note that it doesn't replace the code already in the "Windows Form Designer generated code" region; this is an additional (overloaded) constructor.

Next, Form2 needs this declaration in the usual declarations area (ie. outside of any other code blocks) :

<!-- Generated using PrettyCode.Encoder at http://www.vbcity.com/encoder --><!-- PrettyCode.Encoder Copyright (c) 2000 vbCity.com --><!-- START http://www.vbcity.com/encoder -->
 
<!-- END http://www.vbcity.com/encoder -->

For this example, I have used the variation which bypasses the Closing event and simply hides Form2, but this is optional if it doesn't suit your purposes. The logic is the same if you do want Form2 to be closed, not merely hidden.

<!-- Generated using PrettyCode.Encoder at http://www.vbcity.com/encoder --><!-- PrettyCode.Encoder Copyright (c) 2000 vbCity.com --><!-- START http://www.vbcity.com/encoder -->








<!-- END http://www.vbcity.com/encoder -->

(If you don't want to bypass the Closing event as shown above, then you can put a button on your Form2 and use the code above, but without the e.Cancel = True line.)

A happy side effect of using this approach is that it also gets round the problem of unwanted multiple instances of Form2. Obviously, because Form1 is hidden whenever Form2 is on display, the user can't get to the button to fire up another Form2 instance.

Summary

This article has only covered a sample cross-section of some of the ways you can open multiple forms. There are other techniques (MDI, 'Form within a form' and owned forms, for example) that haven't been included here. But hopefully there is enough information here for most purposes in the early days of your journey up that long and tiring .Net learning curve.

If you do want to see some working code for MDI or owned forms, then you can check out the attached solution. It includes all seven methods above, plus these two.

Of course, opening forms is only part of the story. You will also need a grasp of how to pass data between forms and also how to access one form's controls from another form. And finally you will also need to learn a few safe and trusted ways of closing down the forms you want closed, and leaving open those you still need available. Disposal of finished forms is an important part of good development technique. It's planned that these topics will be covered in later parts of this series.

Multiple Forms in VB.NET. Part 2 - Accessing Controls on Other Forms

Article source code: multipleforms2.zip

One of the key mindset changes you have to make as part of your move from VB6 to VB.NET is the status of Windows Forms. In the early days of VB, Forms were King. Now, VB.NET changes the picture and - although they are still important in many applications - Windows Forms should in many cases be viewed as simply another class and be dealt with accordingly.

If you keep this in mind, many of the early learning curve problems of the move to VB.NET are easier to overcome. We dealt with how to load, show, hide and close multiple forms in Multiple Forms in VB.NET: Part 1. You saw there that the answer to most VB6 to VB.NET misunderstandings in this area was to deal with each form as an object of the Form Class.

In this article, we will take an initial look at some ways of accessing other form's controls and passing data between forms; and our approach to this is going to be pretty much the same as in the earlier article.

This is written for fellow .NET Newbies and so it avoids some of the more advanced topics and skills. It is intended only to give you a hand to get started with the basics of accessing one form and its data from another the .NET way, using an object oriented approach. As always with .NET, there's lots of scope for further study!

Accessing Another Form's Controls

When you are dealing with Windows Forms it's quite likely that sooner or later you are going to want to pass the data held in a control on one form over to another form. For example, the text a user has entered in a text box, a selection from a combobox, a checkbox's Checked property, etc. You may also want to insert data into a control on another form.

Remembering that everything in VB.NET is an object, and that we want to leave our VB.Old ways behind us and think OOP, the trick here is to deal with the control we want to access as an object in its own right.

So let's take one of the examples from the first paragraph above and see how we go about achieving this. I'm going to take the first one - passing the text from a textbox in Form2 back to Form1 - as this is relatively common and straightforward.

Example 1: Reading Another Form's TextBox

In this example we'll assume that it's acceptable for the second form to be opened modally (that is, the user can't do anything with the first form until the second form has been closed.) In many cases, this will be fine.

Here are the steps:

  1. Create Two Windows Forms (Form1 and Form2*)
  2. Form1: Add a Button (named 'ShowButton') and a Label (named 'UserLabel').
  3. Form2: Add a TextBox (named 'UsersName') and a Button (named 'CloseButton').

(* It's not usually considered a good idea to use names that don't reveal any information - such as Form1, TextBox1, etc. However, I've kept to Form1 and Form2 in this example as it's useful to make it clear which form is doing the calling and which is being called.)

And now to start the coding. In Form1, we need an Object Variable to manipulate the second form.

<!-- Generated using PrettyCode.Encoder at http://www.vbcity.com/encoder --><!-- PrettyCode.Encoder Copyright (c) 2000 vbCity.com --><!-- START http://www.vbcity.com/encoder -->



<!-- END http://www.vbcity.com/encoder -->

In the Click_Event handler for the ShowButton, enter this code:

<!-- Generated using PrettyCode.Encoder at http://www.vbcity.com/encoder --><!-- PrettyCode.Encoder Copyright (c) 2000 vbCity.com --><!-- START http://www.vbcity.com/encoder -->
 
<!-- END http://www.vbcity.com/encoder -->

There is some more code needed for that button click event, but we'll come back to it in a moment.

In Form2, we create another Object Variable, but this time it will hold a TextBox control, not a Form.

<!-- Generated using PrettyCode.Encoder at http://www.vbcity.com/encoder --><!-- PrettyCode.Encoder Copyright (c) 2000 vbCity.com --><!-- START http://www.vbcity.com/encoder -->



<!-- END http://www.vbcity.com/encoder -->

Notice that the scope of this variable is 'Public Shared'. This is important as this scope declaration makes the variable visible to the other form (and in fact the rest of the application).

Still in Form2, we put the following code in the Click event of the button:

<!-- Generated using PrettyCode.Encoder at http://www.vbcity.com/encoder --><!-- PrettyCode.Encoder Copyright (c) 2000 vbCity.com --><!-- START http://www.vbcity.com/encoder -->






<!-- END http://www.vbcity.com/encoder -->

With that very simple code, we have made the properties of our TextBox in Form2 available to the user back in Form1. NuNameTB is now effectively a TextBox Object, whose Text property is the same as Form2's UsersName.Text property.

I said we'd have to come back to the code block for the ShowButton Click in Form1. If you have entered all the above code and have run it, you will be back with Form1 on view, but there's no evidence that what I have just said is true. So, here's the proof:-

At the bottom of the Click event for Form1's ShowButton, add this:

<!-- Generated using PrettyCode.Encoder at http://www.vbcity.com/encoder --><!-- PrettyCode.Encoder Copyright (c) 2000 vbCity.com --><!-- START http://www.vbcity.com/encoder -->
 
<!-- END http://www.vbcity.com/encoder -->

Run this now and, once you've closed down Form2, you will see that whatever you typed into the TextBox on Form2 is available and displayed in the label on Form1.

Note that although this example uses the most obvious property of the TextBox (the Text property), you can in fact access any of that TextBox's properties if you need to. By the way, if you're wondering why we've done it this way with an object variable and not accessed the textbox directly, then the plain answer is 'Think OOP'.

Example 2: Using a Property Procedure

So that was a fairly uncomplicated example which will do the job for you in many circumstances. Let's rack up the OOP factor another notch and this time use a Property Procedure as our means of passing the data around. This fits in with one of the cornerstones of OOP - Abstraction.

In my non-technical way, I like to think of Abstraction as the provision of a general purpose front end that continues to function properly even if we tweak about with the code at the 'back end'. In the example that follows, for instance, we could remove the textbox from Form2 and use some other means of feeding data into its UserName Property. The code in Form1 would be oblivious to the change and still work perfectly well.

I am again going to use a textbox as the control we are focusing on, but don't let this give you the mistaken impression that you are limited to textboxes. They just happen to be easy to use as examples. Set up your project as follows:

  1. Create Two Windows Forms (Form1 and Form2)
  2. Form1: Add a Button (named 'ShowButton') and a Label (named 'UserLabel').
  3. Form2: Add a TextBox (named 'UsersNameTextBox').

As in the previous example, we need an Object Variable In Form1 to allow us to show the second form.

<!-- Generated using PrettyCode.Encoder at http://www.vbcity.com/encoder --><!-- PrettyCode.Encoder Copyright (c) 2000 vbCity.com --><!-- START http://www.vbcity.com/encoder -->



<!-- END http://www.vbcity.com/encoder -->

And we can add this code to Form1's Load event in order to have both forms on view at the same time:

<!-- Generated using PrettyCode.Encoder at http://www.vbcity.com/encoder --><!-- PrettyCode.Encoder Copyright (c) 2000 vbCity.com --><!-- START http://www.vbcity.com/encoder -->
 
<!-- END http://www.vbcity.com/encoder -->

So far, this example and the previous one are very similar. We start to diverge at this point. Let's create that Property on Form2 which will hold the contents of TextBox1 (or whatever else we later choose to store in the UserName property).

In Form2, we will create a ReadOnly Property called UserName. Why Read Only? Well, it's not strictly necessary, but for the purposes of this simple example it will ensure that data cannot be passed back from Form1 and used to populate the TextBox in Form2.

Here's the code to go into Form2:

<!-- Generated using PrettyCode.Encoder at http://www.vbcity.com/encoder --><!-- PrettyCode.Encoder Copyright (c) 2000 vbCity.com --><!-- START http://www.vbcity.com/encoder -->




<!-- END http://www.vbcity.com/encoder -->

As you can see, all this Property does is hold the value of the text that the user enters into the textbox on Form2.

Now, what we want to happen is that when the user clicks on the button in Form1, the label on Form1 will be updated with the contents of the textbox on Form2. (Actually, to be more accurate, the contents of the UserName Property from Form2, remembering what I said earlier about Abstraction).

So in Form1, in the Click_Event handler for the ShowButton, enter this code:

<!-- Generated using PrettyCode.Encoder at http://www.vbcity.com/encoder --><!-- PrettyCode.Encoder Copyright (c) 2000 vbCity.com --><!-- START http://www.vbcity.com/encoder -->



<!-- END http://www.vbcity.com/encoder -->

To see this example working, run the project and make sure that you have positioned the two forms so that you can see both on the screen at the same time. Enter a name into the textbox on Form2. Click on the button on Form1. The label on Form1 will be updated with whatever you have entered into that textbox.

Change the textbox entry, click the button again and the label will change accordingly.

OK, now no-one's pretending that this is anything like a real-world scenario; it's a very artificial project, designed only to demonstrate that you can pass the data from the control on one form to a control on another form. Structurally it has more holes than a piece of Gruyere cheese, but it serves its purpose. Hopefully, you can see more realistic ways in which you can employ this basic technique.

The attached Solution includes the two examples from this article.

In the next article, we will look at rather more dynamic ways of getting hold of this cross-forms data. By this I mean the kind of scenarios where Form1 can be automatically updated when data in Form2 changes - no more of this 'pressing a button to make something happen' nonsense. We'll be tying our Form Properties in with Events and Event Handlers for a much slicker, user friendly and professional looking application. But in the meantime the two examples in this article have at least got the basics under our belts.

Multiple Forms in VB.NET. Part 3 - Using Events in Multiple Forms

Article source code: multipleforms3.zip

As with the previous articles in this series, this one is also aimed at .NET Newbies and Upgraders. It tries to explain concepts as simply as possible, with the greatest use of plain English and minimum use of technical terms. The aim is to get the core ideas across as quickly as possible, so you can achieve the results you desire now; the technical details can follow in time. I know that many will not agree with this approach, but as a relative .NET Newbie myself, I know just how frustrating it can be trying to plough through a mass of technical detail in the early days when all you really want to do is, well, get started!

In this article, we are going to look at another topic on ways of dealing with multiple forms. As promised at the end of Part 2, we are first going to take a look at a way of passing data between multiple forms, but this time the user doesn't need to click a button to fire up the event.

Using Events

In our example project, we will have two forms. As the user enters data into a textbox in one form, this data will be copied to a label in the second form. Once again, although we're using a simple textbox for this example of the technique, the core idea can be extended for use in many much more sophisticated ways.

So, create two Windows Forms and name them EventsForm1 and EventsForm2. We'll be using EventsForm1 as the 'main' form, which is the one that has the label to receive the input data, and EventsForm2 as the form with the input textbox.

Here's the code we need to create an instance of EventsForm2. First, in EventsForm1, we declare a Form variable.

<!-- Generated using PrettyCode.Encoder at http://www.vbcity.com/encoder --><!-- PrettyCode.Encoder Copyright (c) 2000 vbCity.com --><!-- START http://www.vbcity.com/encoder -->

<!-- END http://www.vbcity.com/encoder -->

Note that this has been declared WithEvents. This is important and if you leave it out, the main form will not be aware of what we are about to do in the second form.

And I thought that as we are being more dynamic in this Part, we would also instantiate and show the second form without user intervention. Or, in other words, we'll put it in the first form's load event and both forms will appear to the user at the same time.

<!-- Generated using PrettyCode.Encoder at http://www.vbcity.com/encoder --><!-- PrettyCode.Encoder Copyright (c) 2000 vbCity.com --><!-- START http://www.vbcity.com/encoder -->





















<!-- END http://www.vbcity.com/encoder -->

Apart from the couple of lines at the end of that block, which just ensure that the two forms can be seen side by side, the instantiation code is the "test before instantiating" code which we covered in Part 1. (The code in Part 1 is quite well commented if you want to see the details.)

Add Some Controls

If you were to run the project at this point, you will be rewarded with two control-free forms side by side on your screen. Time to add some GUI items then.

In EventsForm1, add a Label. The size isn't critical, but you should allow for several lines of text to be visible. We'll name this label lblData.

In EventsForm2, add a Textbox. Delete the default Text property (usually this will be 'TextBox1') so that the user will see an empty textbox. Also set its MultiLine property to True. Finally, rename it as TB1.

The Events Code

Just to quickly recap what we are trying to do here: When the user types something into the textbox TB1 in EventsForm2, we want the text also to be displayed in the label in EventsForm1.

Let's add in the code to achieve this. We first need to declare an Event. We'll call this event TextHasChanged.

Here's the declaration; note that it has to be placed outside any code blocks, subs, etc.

<!-- Generated using PrettyCode.Encoder at http://www.vbcity.com/encoder --><!-- PrettyCode.Encoder Copyright (c) 2000 vbCity.com --><!-- START http://www.vbcity.com/encoder -->




<!-- END http://www.vbcity.com/encoder -->

Now, we need something to fire up this event. The obvious candidate in this particular scenario is the built-in TextChanged event of the textbox, so let's put some code in there to raise the warning flag that we are creating here.

Select the textbox TB1 in the code window and put this code in its TextChanged event handler:

<!-- Generated using PrettyCode.Encoder at http://www.vbcity.com/encoder --><!-- PrettyCode.Encoder Copyright (c) 2000 vbCity.com --><!-- START http://www.vbcity.com/encoder -->






<!-- END http://www.vbcity.com/encoder -->

All this does is to flag up the fact that text has changed by raising the Event that we declared and called TextHasChanged.

What will happen each time the user enters any character into the textbox is that the TextHasChanged event is raised. (This includes any editing of the text with the Delete or BackSpace keys too).

However, there's no point in waving the flag around (raising the event) if there's no lifeguard (in this case EventsForm1) looking out for it. So, finally, we'll tell EventsForm1 what to do if the TextHasChanged event in EventsForm1 is raised. (Technically, this is known as receiving the event.)

Back in EventsForm1, if you go into the Code Window and click on the left hand combo, you will see that the Object we have named f2 is available in that drop down list of Objects. Select it and then click on the right hand list of Events. You will see that our newly created event TextHasChanged is now included in the list of events, along with all the usual Windows Forms events that you'd expect to see there.

So let's select that item from the list and we will be able to put some code in the TextHasChanged Event's Event Handler:

<!-- Generated using PrettyCode.Encoder at http://www.vbcity.com/encoder --><!-- PrettyCode.Encoder Copyright (c) 2000 vbCity.com --><!-- START http://www.vbcity.com/encoder -->


<!-- END http://www.vbcity.com/encoder -->

You'll understand that all this code really does is to copy the text from the textbox on the other form into the label on this form. But because we have linked this event to react to every change of character in that textbox, the user will see the text displayed in the label dynamically as it is being typed. If you run the project now and type in some text, you will see this in action.

Summary

There are of course always alternative ways of achieving the same result, but I took the example of a textbox used here as a simple demonstration of the sort of thing you can do with passing events between multiple forms. It's sometimes difficult to find examples that aren't too artificial, but hopefully this basic example will be enough to show you how to use the technique in a variety of more advanced and exciting ways, according to your needs in projects and applications. I hope you find it a useful introduction to the very basics of Events, as well as simply showing you another way of passing data between multiple forms.

My thanks to fellow vbCity Member George Poth for proofreading this article and for creating the attached Visual Studio Solution from the narrative.

Multiple Forms in VB.NET. Part 4 - Accessing Controls and Data on the StartUp Form

Article source code: multipleforms4.zip

Introduction

In previous articles, we looked at some common problems that seem to have caused problems for many newcomers to VB.NET. In this article we will take a look at a specific area which appears to contribute more than its fair share of grief to many people in the early days of the .NET learning curve.

As with all the previous articles, this one is aimed squarely at .NET Newbies and tries to provide explanation and solutions with the least possible amount of techno-speak. Inevitably this sometimes means that strict technical accuracy has to take a back seat where a tricky concept is being explained, but it's all in a good cause!

The Background

Some of the previous articles have covered methods of accessing controls and data between multiple forms. On the whole, though, those articles have tended to use examples which get information from a second form in order to use it or show it in the Startup Form. This time we are going to concentrate on the reverse requirement – getting data or accessing a control from the startup form and using it in another form. Until you know how, this is not quite as easy as most of us would think it should be.

So, what is the big difference that causes us problems when we want to refer back to our startup form, Form1? Well, what those other forms need is a reference that they can use in order to get at that first form. As I've mentioned in previous articles, a lot of the trouble is caused by the way we've come to think of Forms as being different from other objects, due to our VB.Old upbringing. There's also a rather unhelpful smokescreen unwittingly caused by the way that this startup object (Form1) is automatically created for you in Visual Studio as the project fires up and runs.

You know that when you need to create an instance of Form2, you use code such as:

<!-- Generated using PrettyCode.Encoder at http://www.vbcity.com/encoder --><!-- PrettyCode.Encoder Copyright (c) 2000 vbCity.com --><!-- START http://www.vbcity.com/encoder -->


<!-- END http://www.vbcity.com/encoder -->

and you'll be aware that F2 is a variable which holds a reference to that instance of a Form2 object. Once you have that reference in your object variable, you can access the properties or invoke the methods and events of that Form2 instance – BUT, and this is the key issue here – you can only do it via that F2 variable that you created.

At the risk of labouring it, the point I'm making here is that there is no

Form2.Show

in the example above. Form2 is the Class; F2 is a variable that holds a reference to an instance of that class. Just like any other object

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在码农的生活,很多级码农都有这样的经历,会被一个小小的技术问题拦住,然后进度跟不上了,被老板XXXX一大通了。心情不爽了。 好吧,这个曾经是我遇到拦路虎之一。但事实上不是什么大技术。技术就是一层纸,破了就破了。 这是一个关于如何跨窗体操作控件或过程的一个例子。比如,你想用窗体A的按键来执行窗体B的文本框变色。 Imports System Imports System.Threading Imports System.Text Public Class Form1 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load CheckForIllegalCrossThreadCalls = False '不写这行,会出错,不允许线程的数据写到TextBox1.Text 去。 Form2.Show() End Sub Private Sub form1_FormClosing(sender As Object, e As EventArgs) Handles Me.FormClosing ' If runThread.IsAlive = True Then runThread.Abort() End Sub Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click '用的是委托方式 Me.Invoke(New MethodInvoker(AddressOf THREAD2)) End Sub Private Sub THREAD2() Static j As Integer j = j + 1 TextBox1.Text = " 这是 [线程] 操作" & vbCrLf & _ " Button2被点了: " & j & " 次" & vbCrLf & "要求是from2.textbox.text= textbox1.text 。[问题]但为什么不能成功显示呢?" End Sub Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged Form2.TextBox1.Text = TextBox1.Text End Sub Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click Static j As Integer j = j + 1 TextBox1.Text = " 这是 [非线程] 操作" & vbCrLf & _ "Button3 点击了: " & j & " 次" & vbCrLf & _ "要求是from2.textbox.text= textbox1.text, 可以成功显示,这个是对的。" End Sub End Class

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值