how to generically open a form from another form? - c#

I have a total of 6 forms. In my mainForm, I have 5 buttons to open the other forms inside the panel. what i know is something like this:
form1 f1 = new form1();
f1.TopLevel = false;
f1.Dock = DockStyle.Fill;
this.panelMid.Controls.Add(f1);
f1.show();
now, since I have 5 other forms, I want to make a function that would make me open the forms without re-typing those code in every button event.
My problem is that I don't know to pass the form into a function as parameter.

DRY 101, based on your code, with some generics chucked in
public void MyAwesomeFormShower<TForm>()
where TForm : Form, new()
{
var form = new TForm();
// common code here
form.TopLevel = false;
form.Dock = DockStyle.Fill;
///this.panelMid.Controls.Add(f1); // < who knows what this does, however don't do it
form.Show();
}
Usage
MyAwesomeFormShower<MyLovelyHorseForm>();
Or if you want to get fancy
public void MyAwesomeFormShower<TForm>(Action<TForm> action = null)
where TForm : Form, new()
{
var form = new TForm();
// common code here
form.TopLevel = false;
form.Dock = DockStyle.Fill;
action?.Invoke();
form.Show();
}
Usage
MyAwesomeFormShower<MyLovelyHorseForm>();
// or
MyAwesomeFormShower<MyLovelyHorseForm>((form) =>
{
// Specialised form stuff here
// that is specific to MyLovelyHorseForm
});

Related

C# Using function from another file

Ok, so, I have functions.cs file where i stored following function
public static void Global_Reset()
{
Form1 blok = new Form1();
blok.userControl1.Visible = false;
blok.userControl2.Visible = false;
blok.userControl3.Visible = false;
if (Properties.Settings.Default.client == 1)
{
blok.userControl1.Visible = true;
MessageBox.Show("First");
}
else if (Properties.Settings.Default.client == 2)
{
blok.userControl2.Visible = true;
MessageBox.Show("Second");
}
else if (Properties.Settings.Default.client == 3)
{
blok.userControl2.Visible = true;
MessageBox.Show("Third");
}
else
{
MessageBox.Show("Error");
}
}
When I call fun.Global_Reset() in Form1 or in any user control that is used in Form1, visibility never changes but I got messages (First, Second, Third). Is there any way to solve this?
I tried to use this directly in Form1 and it used to work, but when I call it from userControl that was used in Form1 it's not working again.
This is the form you're modifying:
Form1 blok = new Form1();
It only exists during the scope of that method (function), and it is never shown to the user. It's not the form instance you're seeing on the screen.
As an analogy... Imagine the form you're seeing is a car. What you're doing is getting another car that looks just like it and putting something in the trunk of that car, then noticing that what you put in the trunk of the second car can't be found in the trunk of the first car.
Instead of creating a new form instance, pass the existing instance to this method:
public static void Global_Reset(Form1 blok)
{
// don't create an instance here, just use the blok that was passed
}
Then pass that instance from your form, for example:
fun.Global_Reset(this);

How to affect child form from parent form in mdi c#

My problem is that I have created child's object and show child first time. but when second time I just want to change value of child's label from parent but don't want to show another form.
Here is my code.
First time
ChildForm ObjChild = new ChildForm("Hi");
ObjChild.Show();
On second time I just want to set Bye in place of Hi.
ChildForm ObjChild = new ChildForm("H!");
ObjChild.BringToFront();
Because child form is already opened.
This is my child Form
public Form1(string p_Param)
{
InitializeComponent();
Label1.Text = p_Param;
}
Constructors call one time when object created. You must implement a new public void or function rather than a constructor to do that.
public void ChangeLabelText(string txt)
{
Label1.Text=txt;
}
EDIT:
In your parent form;
Out of functions;
chilFrm ChildForm;
Inside any function;
if (chilFrm == null)
{
chilFrm = new ChildForm();
chilFrm.TopLevel = false;
chilFrm.Parent = this;
chilFrm.StartUpProsecc("Created New");
chilFrm.Show();
}
else
{
chilFrm.StartUpProsecc("Showed the existing.");
chilFrm.BringToFront();
}

c# - Methods that are called from another class are not running

I am having trouble doing something that I would have though to have been quite simple, all I am trying to do is to call a method from another class, heres how I am calling the method:
Gimjes_2D_Game_Framework1.Characters.Character_One.Create();
and here is the contents of the method I am trying to call:
public static void Create()
{
Form1 f = new Form1();
System.Windows.Forms.PictureBox s = new System.Windows.Forms.PictureBox();
//location of image (in thia case it is from resources):
s.BackgroundImage = Gimjes_2D_Game_Framework1.Properties.Resources.DefaultSprite;
//Set to height and width of image:
s.Height = 64;
s.Width = 64;
s.Size = new System.Drawing.Size(60, 60);
s.Location = new System.Drawing.Point(50, 50);
f.Controls.Add(s);
}
Try adding
f.Show();
or
f.ShowDialog();
to the end of your Create method.
Otherwise, you're making a form, and never displaying it.
Show gives you a modeless form, and ShowDialog gives you a modal dialog.
See documentation here for more information.
If you intend to return a Form1 object, to be shown at a later point, you need to change your method to:
public static Form1 Create()
{
Form1 f = new Form1();
...
return f;
}

Deleting old winform and tray icon when I make a new winform

In my application I have two winforms. The first acts as my control panel and the second I use to take screen shots. However, when I go from Winform 2 back to Winform 1 I have a new winform created and a brand new tray icon. This is on top of the initial ones I create when the program first starts.
When I go from winform 1 to winform 2 I do the following:
this.Hide();
Form2 form2 = new Form2();
form2.InstanceRef = this;
form2.Show();
Then when I want to go back from Winform 2 to Winform 1 I do the following:
this.Close();
Winform1 form;
form = new Winform1 (capturedImageObj);
form.Show();
I know straight off the bat the issue falls on the fact I'm creating a new Winform1, but I need to do that so I can pass my capturedImageObj back into Winform 1.
I've tried calling this.close() and this.dispose() in the my first section of code but that only closes the program down. Is there a way I can dispose of Winform 1 but still use Winform 2 and pass the object I need to back into a new copy of Winform 1?
Here is the constructor for my Winform 1:
public ControlPanel(Image imjObj)
{
InitializeComponent();
_screenCap = new ScreenCapture();
_screenCap.OnUpdateStatus += _screen_CapOnUpdateStatus;
capturedImage = imjObj;
imagePreview.Image = capturedImage;
}
Change Winform1 to use properties like this:
public Image CapturedImage {
get { return imagePreview.Image; }
set { imagePreview.Image = value; }
}
Then change your constructor like this:
public ControlPanel(Image imjObj)
{
InitializeComponent();
_screenCap = new ScreenCapture();
_screenCap.OnUpdateStatus += _screen_CapOnUpdateStatus;
CapturedImage = imjObj;
}
And, finally, change your Winform2 to do this:
((Winform1)this.InstanceRef).CapturedImage = capturedImageObj;
this.InstanceRef.Show();
this.Close();
Based on the comment, it sounds like your InstanceRef property is of type Form. Change it to be of type Winform1. Or, I changed the code above to do some casting for you.

Adding Controls to Form from another class

I have a program, which creates one pictureBox in Form1, and then creates an instance of a class that I called InitialState. The InitialState puts the source to the Image so that it is displayed, and after some time has passed, for which I used a Timer, it creates the next class, MainMenuState. Now, in that MainMenuState class that I've created, I would like to create another pictureBox and make it display on that Form1. Later on, I would like to make the pictures inside it change a bit, and then (possibly) destroy that pictureBox. After that, the program enters the next state (which is in yet another class), and again I would like that class to add a picture box to the original form, and so on.
Basically, I would like to dynamically add controls to the main Form1, but not in the said form, but from the classes I create later on. I've been searching on the internet for a way to do that, and it seems like I would have to use a delegate in order to invoke the Controls.Add method of the Form1 class. I've tried that, and the code compiles, but the pictureBox still doesn't show up.
Here's my code:
Form1 class:
public const string RESOURCE_PATH = "C:/Users/Noel/Documents/Visual Studio 2010/Projects/A/Resources/Animations/";
public Form1()
{
InitializeComponent(); //here, the first pictureBox shows
iInitializeComponent();
zacetnaAnimacija.Dock = DockStyle.Fill; //zacetnaAnimacija is the first pictureBox that appears
zacetnaAnimacija.Anchor = AnchorStyles.Top | AnchorStyles.Left;
zacetnaAnimacija.SizeMode = PictureBoxSizeMode.StretchImage;
InitialState intialState = new InitialState(this, zacetnaAnimacija); //entering InitialState
}
InitialState class:
class InitialState : State
{
System.Timers.Timer initialTimer;
PictureBox pictureBox1;
Form1 form;
public InitialState (Form1 form, PictureBox pictureBox1) {
this.form = form;
GifImage zacetnaSlika = new GifImage(Form1.RESOURCE_PATH + "Presenting.gif"); //this is just a .gif picture I'm displaying
Image trenutnaSlika = zacetnaSlika.GetFrame(0); //a method that plays the .gif
pictureBox1.Image = trenutnaSlika; //makes the first .gif display
this.pictureBox1 = pictureBox1;
initialTimer = new System.Timers.Timer(2500);
initialTimer.Enabled = true;
initialTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
}
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
initialTimer.Enabled = false;
MainMenuState menuState = new MainMenuState(form, pictureBox1); //enters main menu state with the Form1 argument passed on
}
MainMenuState class:
class MainMenuState : State
{
Form1 form;
public MainMenuState (Form1 form, PictureBox pictureBox1) {
this.form = form;
GifImage zacetnaSlika = new GifImage(Form1.RESOURCE_PATH + "animated.gif");
Image trenutnaSlika = zacetnaSlika.GetFrame(0);
pictureBox1.Image = trenutnaSlika; //this simply makes another .gif appear in the picture box instead of the first one
PictureBox a = new PictureBox(); //HERE'S my problem, when I want to add ANOTHER pictureBox to that form.
a.BackgroundImage = trenutnaSlika;
a.Location = new System.Drawing.Point(0, 0);
a.Name = "zacetnaAnimacija";
a.Size = new System.Drawing.Size(150, 150);
a.TabIndex = 1;
a.TabStop = false;
AddControl(a); //calling the delegate
}
public delegate void AddControls(PictureBox a);
public void AddControl(PictureBox a)
{
if (form.InvokeRequired)
{
AddControls del = new AddControls(AddControl);
form.Invoke(del, new object[] { a });
}
else
{
form.Controls.Add(a);
}
}
As I've said, the code compiles, but it doesn't create the PictureBox a on the Form1, when the MainMenuState is created. The thing is, if I don't use the delegate in the MainMenuState and just try to do something like form.Controls.Add(a), then I get a "cross-thread operation not valid" exception, and it doesn't even compile. That's why I used the delegate, but even now, it doesn't work.
Can someone please help me?
initialTimer = new System.Timers.Timer(2500);
That's part of the reason you're having trouble. The Elapsed event runs on a threadpool thread, forcing you to do the BeginInvoke song and dance. Use a System.Windows.Forms.Timer instead, its Tick event runs on the UI thread.
You'll also run into trouble with memory management, these classes need to implement IDisposable.
Oh my God, I just found the reason X_x
It was the fact that since the first pictureBox was covering the entire form, and the second one, which was created by the delegate, showed behind it! I just need to bring it to front!
Thank you guys, nonetheless, I probably wouldn't have come to that without you.
Edit: However, may I ask how to bring that control to the front? The a.BringToFront() function doesn't seem to work.
Instead of
form.Invoke(del, new object[]{a});
try:
form.Invoke(new ThreadStart(delegate
{
form.Controls.Add(a);
}
));

Categories