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.
Related
I'm almost done doing a Connect4 game with VS2012 using WinForms. Everything is working well but I wanted to bring the options for the user on a dedicated Start Menu window. On that menu I have two comboBoxes I need to take the text from to use them as a value for two variables in my other form (the game window). I also have one New Game button that should call a method from my other form if that's possible (basically, I made an "Initialization()" method in my game form and I'd like it to be launched when I click the "New Game" button on the other form).
I only found tutorials that show how to do very basic things from one form to an other (such as labeling texts) but I I didn't find an answer to my specific problem.
I used this in my main form to instantiate the menu form
public FormMenu myMenu;
myMenu = new FormMenu();
What I want to do is that I could do something like this in the other form :
amountOfRows = Int32.Parse(myMenu.comboBoxRows.Text);
amountOfColumns = Int32.Parse(myMenu.comboBoxColumns.Text);
Any idea how I could do that?
I would love to see some example code so I can help see where your confusion lies. WinForms requires the other form to be instantiated.
OtherForm form = new OtherForm();
Once the form is instantiated you should be able to run code from it.
EDIT:
Based on your implementation I would suggest making public methods within FormMenu that return these int values.
public int ReturnRows()
{
return Int32.Parse(myMenu.comboBoxRows.Text);
}
public int ReturnColumns()
{
return Int32.Parse(myMenu.comboBoxColumns.Text);
}
Then from the other form in which myMenu is instantiated you can call myMenu.ReturnRows() and myMenu.ReturnColumns()
The easiest way would be to store a reference to your form in the menue as a variable. (you already named it myMenu)
Then you should create the property/properties you need in the form an add a setter for the values. (see example here)
Last you update the form fields with
myMenu.property = newvalue;
That`s all about it
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();
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
Suppose I create a window form Form.cs. It has some controls(label1, label2, button1, button1 etc.). I also create a new window form New_Form.cs under Form.cs. Now I want to access label1, label2, button1 in New_Form.cs. How can I do this?
I don't want to be offensive, but I think that using control from another form is not a good design.
In my oppinion it is not good to couple one class (in this question form1) to the inner implementation of another class (controls of `form2´. If you, for some reason, have to change the inner design (e.g. showing the data with a different control) of that class, you have to change the other class too. That makes coding (and of course error searching) quite difficult.
If there is a need to exchange data between two classes, I would prefer using publioc Properties for that. In the inner design you can attach them to a control, but then this "coupling" stays in the same class)
Although this can be bad design, you can access properties in another Form by making them public and then accessing them like this:
Form1 frm = new Form1();
Form1.button1.Visible = false;
Also here is an msdn page pertaining to your question
http://msdn.microsoft.com/en-us/library/f6525896%28v=vs.90%29.aspx
You can access the required properties by setting them as public properties in your Parent form. Not sure as why you would want the button, if you want some thing to be executed for the click then you should encapsulate the logic into separate methods and them make the call.
If you have fewer details to pass then make constructors for the new form which would accept those values
ChildForm child = new ChildForm([label1], [label2])
or
ChildForm child = new ChildForm([parent form reference]) // so you could access require components
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; }
}
// ...
}