I have created a form with 5 static tabs and then created 5 separate forms that load in to them at Main form load. The first of these tabs has buttons on the form that I want to link to and show the corresponding tab when clicked.
The problem I'm having is that the buttons not being on the main form but a separate form don't have the options to switch to the corresponding tab on the main form.
I have tried the tabControl1.SelectedTab = tabPage2 stumped me for a couple of days this one any help much appreciated
As I understand your question, your problem is "How to communicate the button click on the sub form to the main form".
I'd suggest to declare events in your sub forms and catch these events in your main form. So a simplified example of a sub form could look like this:
public class SubForm : Form
{
// this is the event to register with from MainForm
public event EventHandler ButtonClicked;
// thread safe event invocator (standard pattern)
protected virtual void OnButtonClicked()
{
EventHandler handler = ButtonClicked;
if (handler != null) handler(this, EventArgs.Empty);
}
// your button handler
private void button1_Clicked(object sender, Eventargs e)
{
OnButtonClicked();
}
}
And in your main form you could do the following:
public class MainForm : Form
{
private SubForm _subForm1 = new SubForm();
private SubForm _subForm2 = new SubForm();
public MainForm()
{
InitializeComponents();
// more initializatino
_subForm1.ButtonClicked += subForm1_ButtonClicked;
_subForm2.ButtonClicked += subForm2_ButtonClicked;
}
private void subForm1_ButtonClicked(object sender, EventArgs e)
{
tabControl1.SelectedTab = tabPage1;
}
private void subForm2_ButtonClicked(object sender, EventArgs e)
{
tabControl1.SelectedTab = tabPage2;
}
And you can also think about using only one someSubForm_ButtonClicked handler and infer which tab to select via the sender argument, which will be the SubForm that raised the event.
Related
I am building a game. I have a Menu page, with a "Start" button. I would like to know how I can make the button direct the user to a new page with the game. I thought of simply changing all buttons' and labels' visibility to false, but that would be very messy. I thought of closing the form and reopening a new one as said here:
http://social.msdn.microsoft.com/Forums/windows/en-US/936c8ca3-0809-4ddb-890c-426521fe60f1/c-open-a-new-form-and-close-a-form?forum=winforms
Like this:
public static void ThreadProc()
{
Application.Run(new Form());
}
private void button1_Click(object sender, EventArgs e)
{
System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(ThreadProc));
t.Start();
this.Close();
}
but when I click the button, you can see the form closing and reopening again, and it doesn't even reopen at the same coordinates.
Is there any way to do such a thing? I want it to move from page to page as it would if this was a website. Is this possible? If so how? Thanks in advance :-)
Use UserControls for every view you need and then switch between them in your code by adding/removing them to/from your form.
Example: The start-page is a UserControl containing the button that starts the game. The game UI is another UserControl that contains all the logic and visuals for your game.
You could then use something like he following:
public class StartView : UserControl
{
...
private void btnStart_Click(object sender, EventArgs e)
{
// Raise a separate event upon the button being clicked
if (StartButtonPressed != null)
StartButtonPressed(this, EventArgs.Empty);
}
public event EventHandler<EventArgs> StartButtonPressed;
}
public class GameView : UserControl
{
...
}
public UserControl SwitchView(UserControl newView)
{
UserControl oldControl = null;
if (this.Controls.Count > 0)
{ oldControl = (UserControl)this.Controls[0];
this.Controls.RemoveAt(0);
}
this.Controls.Add(newView);
newView.Dock = DockStyle.Fill;
return oldControl;
}
You can now create the start view in Form_Load:
public void Form_Load(object sender, EventArgs e)
{
StartView v = new StartView();
v.StartButtonPressed += StartButtonPressed;
SwitchView(v);
}
The event handler that reacts to the start button being pressed would do this:
public void StartButtonPressed(object senderView, EventArgs e)
{
GameView v = new GameView();
UserControl old = SwitchView(v);
if (old != null)
old.Dispose();
}
I create a event and handle it on the Form
User Control Code:
public event EventHandler ButtonClick;
private void button1_Click(object sender, EventArgs e)
{
if (this.ButtonClick != null)
this.ButtonClick(sender, e);
}
Form Code:
private Usercontrol1 sampleUserControl = new Usercontrol1();
public Form1()
{
InitializeComponent();
sampleUserControl.ButtonClick += new EventHandler(this.UserControl_ButtonClick);
}
private void UserControl_ButtonClick(object sender, EventArgs e)
{
//sample event stuff
this.Close();
Form2 F2 = new Form2();
F2.Show();
}
but the event does not firing. What must be the problem?
private Usercontrol1 sampleUserControl = new Usercontrol1();
It isn't terribly obvious exactly what button you clicked, but it won't be the button on that user control. You never added it to the form's Controls collection so it is not visible. Fix:
public Form1()
{
InitializeComponent();
this.Controls.Add(sampleUserControl);
sampleUserControl.BringToFront();
sampleUserControl.ButtonClick += new EventHandler(this.UserControl_ButtonClick);
}
With some odds that you now have two of those user controls on your form. One that you previously dropped on the form, possibly with the name "Usercontrol11". And the one you added in code. Either use the designer or write the code, doing it both ways causes this kind of trouble.
i've taken your code and compiled it and the event fired right off, so my answer is that the ButtonClick event that you created and fired in the method button1_Click isn't called because the method is not connected to the event of the button clicked for some reason.
please check that the method is called and that the event ButtonClick have been registered on the moment the method button1_Click was called. if the method was not called, you haven't registered the button1_Click method. otherwise, you might have registered to some other item
public Form1()
{
InitializeComponent();
this.Usercontrol11.ButtonClickEvent += new EventHandler(UserControl_ButtonClick);
}
private void UserControl_ButtonClick(object sender, EventArgs e)
{
//sample event stuff
this.Close();
Form2 F2 = new Form2();
F2.Show();
}
Usercontrol1 is the name of usercontrol. So when I add the usercontrol1 to form i gives me the name Usercontrol11
I am really new to programming and currently working on a C# Windows Forms application.
The problem is the following:
I have a Form with different objects and controls like: tabpages, textboxes, timers, etc .
I also have a UserControl form which I load into one of the main Form's tabpages.
I would like to write a code into the UserControl , how can I manipulate element properties of the main Form.
For example: when I click on a button on the UserControl form It sets the main Form's timer.Enabled control to true.
It is possible to do this, but having the user control access and manipulate the form isn't the cleanest way - it would be better to have the user control raise an event and have the hosting form deal with the event. (e.g. on handling the button click, the form could enable/disable the timer, etc.)
That way you could use the user control in different ways for different forms if need be; and it makes it more obvious what is going on.
Update:
Within your user control, you can declare an event - In the button click, you raise the event:
namespace WindowsFormsApplication1
{
public partial class UserControl1 : UserControl
{
public event EventHandler OnButtonClicked;
public UserControl1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
EventHandler handler = OnButtonClicked;
// if something is listening for this event, let let them know it has occurred
if (handler != null)
{
handler(this, new EventArgs());
}
}
}
}
Then within your form, add the user control. You can then hook into the event:
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
userControl11.OnButtonClicked += userControl11_OnButtonClicked;
}
void userControl11_OnButtonClicked(object sender, EventArgs e)
{
MessageBox.Show("got here");
}
}
}
You may want to rethink what it is you are trying to accomplish. However, to answer your question, it can be done.
The best way to do it is to make a property in your UserControl called MainForm:
public Control MainForm {
get;
set;
}
Then, in your MainForm's Load event, set the property to itself:
userControl1.MainForm = this;
Finally, in your user control, set the MainForm's timer:
protected button_click(object sender, EventArgs e)
{
timerName = "timer1";
EnableTimer(timerName);
}
private void EnableTimer(timerName)
{
var timer = MainForm.Controls.FirstOrDefault(z => z.Name.ToLower().Equals(timerName.ToLower());
if (timer != null)
{
((Timer)timer).Enabled = true;
} else {
// Timer was not found
}
}
This is very simple. It's called events. On the user control you would expose an event with a EventHandler for the form to subscribe to.
public partial class MyUserControl : UserControl
{
/// You can name the event anything you want.
public event EventHandler ButtonSelected;
/// This bubbles the button selected event up to the form.
private void Button1_Clicked(object sender, EventArgs e)
{
if (this.ButtonSelected != null)
{
// You could pass your own custom arguments back to the form here.
this.ButtonSelected(this, e)
}
}
}
Now that we have the user control code we'll implement it in the form code. Probably in the constructor of the form you'll have some code like below.
MyUserControl ctrl = new MyUserControl();
ctrl.ButtonSelected += this.ButtonSelected_OnClick;
Finally in the form code you'll have a method that subscribed to the event like the below code that will set the Timer enabled to true.
private void ButtonSelected_OnClick(object sender, EventArgs e)
{
this.Timer1.Enabled = true;
}
And that's how you allow an event on a user control on a form set an object on the form.
You can set the timer1.Modifiers property to "internal" and access it with an instance to Form1:
form1.timer1.Enabled = true;
You need to have an instance of your class Form1, not the class itself. For example:
// INVALID
Form1.timer1.Enabled = true;
// VALID
var form1 = Form1.ActiveForm;
form1.timer1.Enabled = true;
But this is not a very clean way to do this, you would rather use events as described in NDJ's answer.
You need to put the below code,
(`userControl11.OnButtonClicked += userControl11_OnButtonClicked;`)
in a separate file in Visual Studio. The other file is called 'Form1.Designer.cs', and can be found in the Solution Explorer pane under
Form1 >> Form1.cs >> Form1.Designer.cs.
Hope this helps!
I have a main parent winform in which I have implemented some features and that have a number of child windows. Now I want the functionality I have implemented to run also on the child windows.
For instance, in the parent window I am moving an image on the selection of a checkbox. Now, if this checkbox is checked then the image should also move on the all other child windows.
Note: The image moving on the parent window should disapper and should only show on the opend dialogue or child window.
Please suggest if it is possible.
Try using events.
Create an event for the parent form called ImageMoved.
The child forms should subscribe to this event, and when you move the image, you raise the event, then the child forms will know to do their thing.
Lots of different ways to do this. Simple example:
public partial class Form1 : Form {
public event EventHandler ImageMoved;
private void OnImageMoved() {
if (ImageMoved != null)
ImageMoved(this, new EventArgs());
}
private void button1_Click(object sender, EventArgs e) {
OnImageMoved();
}
private void button2_Click(object sender, EventArgs e) {
Form2 f2 = new Form2(this);
f2.Show();
}
}
Then your child forms could look something like this:
public partial class Form2 : Form {
public Form2(Form1 parentForm) {
InitializeComponent();
parentForm.ImageMoved += new EventHandler(parentForm_ImageMoved);
}
void parentForm_ImageMoved(object sender, EventArgs e) {
MessageBox.Show("Image moved");
}
}
You could also create your own EventArgs class if you want to pass more information, such as which image, etc.
I have a windows form called FormMain in ClientForms project. Now this(FormMain) form opens another form called FormScheduler in Scheduling project.
Now, I want to send a message back to FormMain when a button_click method event is triggered in FormScheduler.
My solution creates a circular dependency. Is there another way, like using delegates ?
Use events.
In your form FormScheduer add a button and the following code:
public event EventHandler ButtonClicked;
private void button1_Click(object sender, EventArgs e) {
if (ButtonClicked != null) {
ButtonClicked(this, EventArgs.Empty);
}
}
In your FormMain, instantiate and display your FormScheduer form like this:
var form = new FormScheduer();
// Listen for the ButtonClicked event...
form.ButtonClicked += form__ButtonClicked;
form.Show();
Your form_ButtonClicked method on FormMain will be called when the button on FormScheduler is clicked:
void form__ButtonClicked(object sender, EventArgs e) {
Console.WriteLine("clicked");
}