I'm having some problems with my form and the business class:
The form does not open until the business class has finished it's work. Every time I call Form1 in Main(), Form1 calls two methods:
InitializeComponents();
testConnection();
testConnection calls the business class and sets the properties of the Form according to the properties of the business class. Like that:
Pingger pingger = new Pingger();
ipLabel.Text = pingger.getLocalIP();
I do not do just these operations, I also do others like the result of a ping. However, Form1 takes a long time to open and when it's open Form1 shows the results. What do I have to do, create Form1, open it, and then after 3 seconds start to process the business class?
What you want is an event raised by your form control. To determine if there is such an event you simply Google the class (ie Form). On the msdn page every property, method and event is listed accompanied with what they do.
What you want is the Shown event. You can add an event to this and then handle whatever it is you want to do. See link below.
http://msdn.microsoft.com/en-us/library/system.windows.forms.form(v=vs.110).aspx
You can subscribe to the Shown event for the form and call your testConnection() method from there.
InitializeComponents();
Shown += (s,e) => testConnection();
You could also use multi-threading to "launch" the testConnection() method. (but then you have the added complexity of making sure the results are in before you rely on them, thread safety, etc...)
I wonder you want to show the form just before the connection is tested?
The idea could be using multi-threading like the Wonderbird suggestion, using some like this:
InitializeComponent();
new Thread(testConnection).Start();
Related
I'm trying to do the following:
I have a form1 with a textBox and the following method:
public void ChangeText()
{
textBox.Text = "A";
}
The application runs a form of class Form1 - We'll call it mainForm.
That main form starts another process that creates another form of class Form1 - Let's call it childForm.
I now want to click a button on mainForm and have the childForm's ChangeText() method called so that the childForm's textBox is the one that is effected.
I've been looking for a while and I can't seem to make it work. I'm not entirely sure it's even possible.
API doesn't seem to give me the option at all and with WCF the method is being called, but the original form is not recognized.
Sure, it's possible, but since the two forms are in different processes, you'll need an inter-process communication (IPC) mechanism like .NET Remoting or Windows Communication Foundation. Or you can use this technique.
Assuming you want to edit logic on the way
--
If mainForm instantiates childForm then it should also hold a reference to it.
i.e. private Form childForm = new Form();
Call mainForm.ChangeText() which will look something like this (this gets called by the event so the parameters will in fact be the event and sender parameters):
public void ChangeText(EventArgs e, Sender sender)
{
this.childForm.ChangeText(EventArgs e, Sender sender)
}
You can also access the textBox directly if you make it public
i.e.
this.childForm.textBox1.Text = text
Corrected accessor mistake as pointed out by another user
I have a static event in a DLL that I use frequently - Toolkit.Dialogs.ExitConfirm
The only way I can use this event is by modifying the line that adds the event in form.Designer.cs. Example:
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
becomes
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(Toolkit.Dialogs.ExitConfirm);
If I try to add it via the Properties->Events page, it gives me this error: 'Toolkit.Dialogs.ExitConfirm' is not a valid identifier.
Is there a way to allow Form Designer to reference events from other classes/namespaces?
Edit: some people work better with visual cues, so here's some images to define the issue: http://imgur.com/a/RaLMg
The first image shows how I have to make it work in Visual Studio - an event that calls an event.
The second image shows what I'm actually trying to do.
The third image is the error that occurs when I key in the method name by hand.
I have a static event in a DLL
You don't, you just have a method. FormClosing is the event, your method can be the event handler method if it has the proper signature. The designer simply doesn't support what you try to do, you'll have to stop trying. There are two sane solutions, both involve writing code in the form class. First you can do it in the constructor:
public Form1() {
InitializeComponent();
this.FormClosing += Toolkit.Dialogs.ExitConfirm;
}
Or the sane one since it doesn't make sense for a class to listen to its own events:
protected override void OnFormClosing(FormClosingEventArgs e) {
Toolkit.Dialogs.ExitConfirm(this, e);
if (!e.Cancel) base.OnFormClosing(e);
}
Which has the great advantage of working properly when you derive another form from this one. Which is also a strong hint to what you are probably really should do. It looks like you are trying to write common code for dialogs. The "Toolkit" namespace suggests as much. Make it work well by having this toolkit implement a base form class instead. Now you can design your form class without any code or event handlers:
public partial class Form1 : Toolkit.Dialogs.BaseDialog {
// etc
}
With the assumption that Toolkit.Dialogs.BaseDialog is a class derived from Form that overrides OnFormClosing(). Maybe it should also have a public property named "ConfirmOnClose" of type bool. which enables the "ExitConfirm" logic. You can set that property in the designer without trouble.
The WinForms designer isn't designed to do that. I'm a little surprised it doesn't lose your event the next time you make a change in the designer.
A few ideas on other ways you could make this work:
You could make a Form class that hooks the event for you, and descend all your other forms from that base class. Then you'd get the behavior everywhere.
You could make a utility method that hooks the event for you, and call it from each form's constructor.
You could make an extension method that hooks the event and then shows the form, and call your extension method everywhere you show your forms (instead of calling Show).
The base class is probably the simplest solution, as long as you aren't already using form inheritance for some other purpose.
You can call this Method 'Toolkit.Dialogs.ExitConfirm' On form closing event of your application form and pass required param to Toolkit.Dialogs.ExitConfirm
I need to call tabControl1_SelectedIndexChanged from Form1 in Form2
I have no idea how do this.
In general, you don't call events from other classes. The idea is that events expose subscribe/unsubscribe behaviour. The implementation can choose to also expose a method which raises the event, but it doesn't have to - and if the control you're using doesn't expose such a method for the SelectedIndexChanged event, you can't force it to.
It's not clear what you're trying to achieve, but you may be able to programmatically select the appropriate tab instead - I'd expect that to raise the appropriate event. Rather than expose the tab control directly from Form1 to Form2 (which I hope are only placeholder names - give your forms meaningful names :) it would be cleaner to expose a method in Form1 to perform the selection of the appropriate tab. That's a more meaningful operation to perform on Form1 - it doesn't rely as heavily on the implementation details. On the other hand, you may be able to create an even cleaner design using MVP patterns (or whatever suits you best).
You should make a public method in the first form that performs the logic you need.
Then, pass an instance of the first form to the second form and call the method on that instance.
As Jon mentioned, you shouldn't make public... Here are some other samples that I've posted previously that explicitly walk through the creation of two forms and how to pass back-and-forth. Check these out
I have this battleship program where i am trying to access a function in another form. This function is used to change the buttons on the game board to either enabled or disabled, depending on who's turn it is. Changing the buttons to enabled and disabled is not my problem. My problem is accessing the function to do it in the other form. I would post code, but it is lengthy and spread between three forms.
Appreciate any help!
Thanks in advance!
Luke
Why not pull the functionality out into its own public class (like ButtonConfigurator or something like that). Then any form can hold a ButtonConfigurator object and use it.
It depends on your code architecture:
Kind of rough one: If you just have several forms Form _form1, Form2 _form2, you can create kind of relationship between them, by, just an example pseudocode:
public class Form1:Form
{
Form2 _form2Object = null;
public Form1(Form2 frm2)
{
_form2Object = frm2;
}
//and after when needed just use that _form2Object to call a mehod on it.
}
More nice one: is declare shared between all your forms event Dispatcher. So when Form1 wants to notify somethign to Form2 it calls Dispatchers relative method, which takes care to call right method on Form2
There could be a lot of other solutions more or less nicer, but it strongly depends on your app architecture. Here I just put down a couple of choices you could have.
Hope this helps.
Regards.
you need pass the instance of the form with Button to the form you call the function, make the function public.
Lets suppose you have a Form form1 which has method method1, that you want to access in Form form2. You could declare that method as public static. This way you could access that method like form1.method1.
Situation: C#, .NET 3.5, WinForms
Objective: Form1 has a Button that can be enabled via the constructor. I.E. the button will only be shown if I call new Form1(true).
We'd like to be able to pass a method via some param from Form2 to Form1 (doesn't have to be on Form1's constructor), and when Form1.Button1 is pressed, Form2.<SomeMethod> should be executed.
We know that we could create a Delegate/Event in Form1 and from Form2 do something like:
Form1.SomeDelegate += new ..... (MyMethodInForm2);
…and then in Form1_ButtonClick we fire the event which, in turn will do the magic in Form2.
But we were wondering if there was a more elegant/new/modern version (Anonymous Methods? Lambda Expressions? Etc.) to accomplish this.
The idea is that "any" form could instanciate a Form1 class and pass its own method to be executed when Form1's button is clicked; but instead of a callback to the caller (form2,3,..n), Form1 executes the passed function (which possibly resides inside the caller). We really don't need these functions to have parameters for now.
Note: The code samples contain simple variable/object names and are not taken from real life, please ignore the simplicity.
UPDATE Sorry for not being more specific, I think that I'll keep using the Delegate/Event model, but for reference, here's what I think is a better description of the situtation:
Form1 is a generic form, that accepts a list of items and displays them. We may pass Employee types or Person Types or any "T". It works ok.
We received a requirement from a customer, asking if it was possible to add an optional button to that little Form1 that, if clicked, it will open another form/execute some method.
That way, if I am using Form1, I could -at runtime- tell the button to open the EmployeeForm, whereas if I am using Form1, the very same button could open the form PersonForm. Now opening a Form is not the only use we'd have for that button, but that's the caller's problem.
Right now, what I've done is what we've said: delegate/event on that Form1 and on the "calling" form we do a Form1.theEvent += stuff, to subscribe to the event. I just wanted to know if there was a better way to accomplish this, as this is how we'd do it in .NET 2.0 and we have just started using .NET 3.5.
It sounds like you're describing the same thing twice.
Subscribing to an event does exactly this - passes a function to Form1, which then executes the function when the event is raised.
You could subscribe to the event using a lambda expression if you want, but you don't have to.
Of course you could put the delegate as a Form1 constructor parameter if you wanted, but I don't see much advantage to doing so in this case.
In short: I think normal events do everything you need. If you have a requirement which events don't handle, please give more information.
Not totally sure what you mean with the form stuff, but you can send in a Func. For example:
public class MyForm<T>
{
private readonly Func<T, bool> predicate;
public MyForm(Func<T, bool> predicate) { this.predicate = predicate }
private void SomeMethod()
{
bool result = predicate();
// Do something
}
}
var form = new MyForm(x => x.Number < 5);
1st:you should declare a public event in Form1.
2nd:you should invoke the event where it is sent to Form1 like Button1_Click
From what I can tell, Form2 is a non-modal dialog that Form1 can update. However Form2 might not have been created yet.
The obvious way to accomplish updating Form2 is using the event model as you have, using Composition and passing Form1 into its constructor.
You could use a delegate and store that but I can't see how that is preferably to passing a reference to the parent Form in.
If you want Form2 to update any type then a simple interface would solve the problem.
Another approach is to expose the Click event of the button by defining a "proxy-event" on the generic form:
public class MyForm<T> : Form
{
public event EventHandler MyClick
{
add { this.theButton.Click += value; }
remove { this.theButton.Click -= value; }
}
// ...
}