C# winform, How to create a form ContainerControl? - c#

Recently I have been researching on how to make your own control. And I have asked in the past (2 days ago) about a Tab Control issue that I am having. Well now I want to create a ContainerControl. Something like the form in the MetroFramework because I want to develop my own custom looking form. So fair this is what I have of the form.
now the problem that I am having is that this is made inside of the form. There isn't a ContainerControl where I just type in like 1 line of code and my form will look like that. In this solution I will need to type in about 30 lines. So when I mean by container control, you change the form object in the form.cs coding and it will change the design of the form.
Example for metro framework.
public partial class Form1 : MetroFramework.Forms.MetroForm
Now if I wanted to create a custom form like the one in the picture. I don't want to add 30 - 50 lines of code per form to do that. I just want to make one form class and then add where the "MetroFramework.Forms.MetroForm" is and replace it with my form. For example
public partial class Form1 : MyFormExampleNamespace.MyForm
And this is what the regular c# winform class structure looks like
public partial class Form1 : Form
So now that I explained what I want, define what I think a form ContainerControl is, and what I want. How could I accomplish my goal? How would I make a ContainerControl. This is what I have tried before
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace GoatUserControls
{
public class GoatForm : Form
{
public GoatForm()
{
this.FormBorderStyle = FormBorderStyle.Fixed3D;
base.FormBorderStyle = FormBorderStyle.Fixed3D;
}
private void InitializeComponent()
{
this.SuspendLayout();
//
// GoatForm
//
this.ClientSize = new System.Drawing.Size(284, 261);
this.Name = "GoatForm";
this.Load += new System.EventHandler(this.GoatForm_Load);
this.ResumeLayout(false);
}
private void GoatForm_Load(object sender, EventArgs e)
{
}
//protected override BorderStyle()
// {
// }
}
}
And this is what I have in the main form
public partial class Form1 : GoatUserControls.GoatForm
So how would I make a form ContainerControl?

Related

Passing data between forms to plot a surface, not working

I have two forms (in the same namespace), Form1 which acquires data from images, and GraphForm, which sould plot the data as a surface graph, using the ILNumerics framework.
I had never done such a construction with two forms (fairly new to C#, and coding as a whole for that matters), and I can't figure out why my code doesn't work, as it's almost copy/pasted from a previous question asked here (Sujith H S answer). I tried other constructions described in various similar questions as well, with the same result : the second form and the ILNumerics plotting interface appear, but are empty.
Here is my version of the answer I linked :
IN FORM1 :
// Form creation
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public static ILInArray<double> CrossCorrExpMatrixReShiftedILN;
//Here is my whole data acquisition code, about 800 lines long
ILInArray<double> CrossCorrExpMatrixReShiftedILN = CrossCorrExpMatrixReShifted;
GraphForm Form2 = new GraphForm();
Form2.Show();
IN GRAPHFORM :
public partial class GraphForm : Form
{
public GraphForm()
{
InitializeComponent();
}
private void GraphForm_Load(object sender, EventArgs e)
{
ILInArray<double> GraphData = Form1.CrossCorrExpMatrixReShiftedILN;
//Here I use GraphData to plot the surface
}
Does anyone have an idea why it doesn't work ?
Have you tried passing the ILInArray<double> object into GraphForm's constructor and setting it to a local variable? So something like the below?
IN FORM1 :
GraphForm Form2 = new GraphForm(CrossCorrExpMatrixReShiftedILN);
Form2.Show();
IN GRAPHFORM :
public partial class GraphForm : Form
{
private ILInArray<double> CrossCorrExpMatrixReShiftedILN;
public GraphForm(ILInArray<double> pCrossCorrExpMatrixReShiftedILN)
{
InitializeComponent();
CrossCorrExpMatrixReShiftedILN = pCrossCorrExpMatrixReShiftedILN;
}
private void GraphForm_Load(object sender, EventArgs e)
{
ILInArray<double> GraphData = CrossCorrExpMatrixReShiftedILN;
//Here I use GraphData to plot the surface
}
I found the solution.
In the design tab for the GraphForm form, the Load event was NOT associated with the GraphForm_Load code bit. I don't know why it didn't associate automatically.
I found this by placing breakdown points along the GraphForm code, and noticing that the GraphForm_Load code didn't run at all.

Load an OpenTK GameWindow inside a Windows form panel?

I have an application made in C# using OpenTk.
this is in a class called ViewPort, and is initialized like this:
namespace OpenTK_viewport
{
class ViewPort : GameWindow
{
.....
my Program.cs is:
[STAThread]
static void Main()
{
using (ViewPort main = new ViewPort())
{
main.Run(60.0);
}
}
This works great, and opens the game window. Now, I want to embed this window inside a UserControl, so i can load it into a panel on an existing Form.
For example, in the project, I have:
namespace OpenTK_viewport
{
public partial class Form3dViewport : UserControl
{
public Form3dViewport()
{
InitializeComponent();
}
private void Form3dViewport_Load(object sender, EventArgs e)
{
}
}
}
I would like to embed the ViewPort class inside this UserControl.
I can't find an example of this anywhere. How can i go about this?
EDIT:
I am able to add a GLControl to the Form instead of a panel. Can I load the Viewport class into this?
Thank you.
Ah, I was looking at it wrong. OpenTK can be run straight inside a Form. As illustrated here:
https://github.com/mono/opentk/blob/master/Source/Examples/OpenTK/GLControl/GLControlGameLoop.cs

How Multiple Forms can Call Same Method on Their Load Event

I have around 20 forms in my Project of C#. I have created a method in a Class. I want all the 20 forms to call that method in their Load event. I can put the Call statement in the Load Event of each form one by one. However, in future the forms may increase. Also, it may be possible that some form gets missed to write that Call statement in its Load event mistakenly.
Is their any logic, that the specific method can handle the load events of all the forms of the Project? We can get the list of all the forms of the project by using System.Reflection. So, is it possible to attach the load events of all these forms to the same specific method of the class?
You can create your custom form and override Onload (or any event)
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
namespace test
{
public class MyForm : Form
{
protected override void OnLoad(EventArgs e)
{
MessageBox.Show("test"); //call your method(s)
base.OnLoad(e);
}
}
}
and your new form
namespace CustomFormProject
{
public partial class Form1 : MyForm
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//MessageBox will be shown automatically from your base (MyForm) class
//other codes
}
}
}
You can do something like this:
public partial class Form2 : MainForm
public partial class Form3 : MainForm
...
...
...
public partial class Form19 : MainForm
public partial class Form20 : MainForm
Inherit the MainForm in your other Forms and call the method in their Form_Load event.
The MainForm is the class in which you've created the method, further which you want to access it in the other forms.
Suppose, the example below is the Method in your MainForm.
public partial class MainForm : Form
{
public Form1()
{
InitializeComponent();
}
public void Msg()
{
MessageBox.Show("Hello");
}
}
Call the method Msg() on the Form2_Load event by first inheriting from the MainForm class:
public partial class Form2 : MainForm
^^^^^^^^
Now, call this method:
private void Form2_Load(object sender, EventArgs e)
{
Msg();
}
Similarly, you do the same thing with the rest of your Forms.

Call method/class from different file

I'm terribly new so I might be completely off track overall with what I'm trying to do.
I don't really know how to ask the question, my english is a bit rocky.
But I have 2 files one containing this:
frmMain.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
}
private void label1_Click(object sender, EventArgs e)
{
Class1 cls = new Class1();
cls.Visibility();
}
}
}
And another file containing this:
Class1.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace WindowsFormsApplication1
{
public partial class Class1
{
public void Visibility()
{
frmMain c = new frmMain();
c.label1.Visible = false;
}
}
}
What I'm trying to get is that when I'm running the program and clicking label1 I want it to disappear.
But it doesn't. I don't get any errors or anything.
Any help is appreciated :).
Thanks in advance.
First: Why are you trying to let the label on your mainform dissappear by using another class?
I would suggest the following:
private void label1_Click(object sender, EventArgs e)
{
label1.Visible = false;
}
I think the reason why your code isn't working is that inside the function Visibility() of Class1 you are creating a new frmMain and on that frmMain you are setting the visible property of label1 to false. So you are actually working with a different form.
You are instantiating a new, separate form. This means the label is being hidden.. but on a hidden form you have created.
You need to pass the current form instance into your other class:
public void Visibility(frmMain mainForm) {
mainForm.label1.Visible = false;
}
Then call it like this:
new Class1().Visibility(this);
What you're doing is you're creating a second instance of your window (which might not be obvious to you, as you're not displaying it). Then you are hiding the label in your second window. Probably not what you intended in the first place.
What you need to do is to pass a reference to your original form to the method you're calling, or (depending what you want to do) a reference to the control you need to hide:
in Class1:
public void Visibility(Control controlToHide)
{
controlToHide.Visible = false;
}
in frmMain.cs
new Class1.Visibility(this.label1)
few more comments:
Naming: do not use names like Class1, label1; I appreciate this is probably
just 'play around with' kind of code, but such names are completely
unreadable when you try to come back to your code later (or get
someone else to have a look)
Naming 2: try to name your methods to describe what they will do - HideControl, or HideLabel is much better than Visiblity
You may want to read some basic C# tutorials to learn about references, instances, parameters, etc.
Other than that, happy C#-ing :)
You do not want to let Class1 know about frmMain. Change it to something like this:
public class Class1
{
public bool GetVisibility()
{
return false;
}
}
And from your form, call it like this:
private void label1_Click(object sender, EventArgs e)
{
Class1 cls = new Class1();
this.Label1.Visible = cls.GetVisibility();
}
Your current implementation of Class1 initializes a new frmMain, hides that form's Label1, does not do anything with that instance (e.g. it does not Show() it) and then returns, not affecting the already instantiated and shown frmMain instance (the one you instantiate Class1 from).
You can change this by passing the label or even the form into Class1, but that is just bad design.
You may change your code this way:
public partial class FrmMain : Form
{
public frmMain()
{
InitializeComponent();
}
private void label1_Click(object sender, EventArgs e)
{
new Class1().Visibility(this);
}
public void Go()
{
this.label1.Visible = false;
}
}
Then
public partial class Class1
{
public void Visibility(FrmMain form)
{
form.Go();
}
}
You are setting the visibility of the label of another form (one that's not being displayed.
this line of code in the Visibility method creates a new object
frmMain c = new frmMain();
It's of the same type as the form being display, but it's a different object, that's not displayed. If you insert a line after the above
c.Show();
you should see the newly created form and also see that the label disappears
However there's a straight forward fix to your problem. Change the event handler to this
private void label1_Click(object sender, EventArgs e)
{
((Label)sender).Visible = false;
}
The sender object is the control that was clicked, and since the event is attached to the label it self. All you need to do is cast the sender to the type of a Label and then you can access the visible property. Alternatively you could do this:
private void label1_Click(object sender, EventArgs e)
{
this.label1.Visible = false;
}
That uses the current object (aka this) and gets the label from that object.

How to disable a form resize at design time?

In my application I am deriving all my forms from a common BaseForm.
Now I need to disable the resizing in the BaseForm so that derived forms are not resizable at design-time.
How to achieve that?
I need it at design-time
This seems to work:
[BaseForm.cs]
namespace WindowsFormsApplication1
{
using System.Windows.Forms;
public partial class BaseForm : Form
{
public BaseForm()
{
InitializeComponent();
this.MaximumSize = this.MinimumSize = this.Size;
}
}
}
[DerivedForm.cs]
namespace WindowsFormsApplication1
{
public partial class DerivedForm : WindowsFormsApplication1.BaseForm
{
public DerivedForm()
{
InitializeComponent();
}
}
}
i used
this.FormBorderStyle = FormBorderStyle.FixedDialog;
this make window form as like dialogBox. so dialog boxes are not resizable by user.
Use the following:
this.FormBorderStyle = FormBorderStyle.FixedSingle;
If you go into design view and look in the form's properties menu, there is a Locked property, which disables resizing of the form.
EDIT
Try setting the MaximumSize and MinimumSize properties to the same value.

Categories

Resources