if (!existed_channel.Contains(channel_name))
{
if (x)
{
tabpagex.BackColor = Color.Ivory;
tabControl1.TabPages.Add(tabpagex);
client_chat c = new client_chat(channel_name, owner); //Here the client_chat is my Winform that do all the chatting thing.
c.TopLevel = false;
c.Visible = true;
c.BackColor = Color.Ivory;
c.FormBorderStyle = FormBorderStyle.None;
c.Dock = DockStyle.Fill;
tabControl1.TabPages[tab_index].Controls.Add(c); //Here i fill up the tabpage with client_chat winform
tab_index++; //Increment the index everytime i add an tabpage.
existed_channel.Add(channel_name); //Add the name of the page to an arraylist, to make sure everytime there is no duplicate page
}
}
As you can see, when i close one of my Winform(on the tabpage), i have to send back data and modify the tab_index.
I am able to close both Winform and tabpage, but struggling how to send the data back.
I know how to send back data from childForm to parentForm, but the situation here is little different.
You could use a global property on the parent that all controls have access to
Related
I'm working on a Agenda using windows forms C#, I'm trying to create a colored picture box for each appointment object in the project. Using this code that is used in a loop for each object in my appointment list im creating each picturebox on the right location on the form1 screen.
PictureBox Point = new PictureBox();
this.Controls.Add(Point);
Point.Location = new Point(obj.Location.X, 45 + obj.Location.Y);
Point.BackColor = color;
Point.Size = new Size(96, 25);
Point.Enabled = false;
Point.Tag = "Point";
Point.TabIndex = 100;
Point.Visible = true;
When I'm calling this method from input on the same form, for example a button click. It will work just fine and create all the picture boxxes as needed. But when I'm calling it from the form2.closed event it wont work. Form 2 is my appointment planner form, when clicking on save on this form it will add a new object to the list, so a new picturebox should be created. I have checked the debug using breakpoints, and strange enough it will go through the create code, but no matter what I do it wont render the pictureboxxes.
I personally think it has to do with the form1 not Initializing when called from form2.closed event. But even when using InitializeComponent(); end Refresh(); inside my code it still doesnt work.
Am I using the wrong event or is there a specific call I need to make to generate the pictureboxxes?
Sorry if my post is lacking code or info, I'm not used to posting on stackoverflow, feel free to ask for more information if needed.
if you run your code from Form2 and you want to add control to Form1 you cannot use "this". Form1 has to be accessible from Form2.
PictureBox Point = new PictureBox();
Point.Location = new Point(obj.Location.X, 45 + obj.Location.Y);
Point.BackColor = color;
Point.Size = new Size(96, 25);
Point.Enabled = false;
Point.Tag = "Point";
Point.TabIndex = 100;
Point.Visible = true;
Form1.Controls.Add(Point);
I am new to C#. I am using windows forms and I have Form1 which contains 2 buttons ( one to create user control at run time and the other creates buttons on user control at run time).
This code creates user control and FlowLayoutPanel (to organize button position) if you click add_UserControl button. And then it creates buttons on FlowLayoutPanel if you click Add_Buttons button and it is all done at run time.
Now in Form1 let's say I created user control and FlowLayoutPanel and then created 5 buttons , how can I save the properties/details of this user control with its FlowLayoutPanel and 5 buttons in SQL database so I can use them later when I run the program? I have been thinking about an idea and I reached the internet but no luck.
Any idea? Please help me. Thank you
public partial class Form1 : Form
{
FlowLayoutPanel FLP = new FlowLayoutPanel();
UserControl uc = new UserControl();
private void add_UserControl_Click(object sender, EventArgs e)
{
uc.Height = 700;
uc.Width = 900;
uc.BackColor = Color.Black;
Controls.Add(uc); //add UserControl on Form1
FLP.Height = 600;
FLP.Width = 800;
FLP.BackColor = Color.DimGray;
uc.Controls.Add(FLP); // add FlowLayoutPanel to UserControl
}
private void Add_Buttons_Click(object sender, EventArgs e)
{
//####### add buttons to FlowLayoutPanel ############
Button dynamicButton = new Button();
dynamicButton.Height = 50;
dynamicButton.Width = 200;
dynamicButton.BackColor = Color.Green;
dynamicButton.ForeColor = Color.Blue;
dynamicButton.Text = "";
FLP.Controls.Add(dynamicButton);
}
}
OK, First you need to create a class that will represent one of the buttons with the properties you need.
class MyButton
{
public string ButtonText {get;set;}
}
Everytime you click and create a button, you actually create an object of this class and add it to a collection or list. Then you would have some other code watching over the collection, and every time it gets a new entry, it creates a new button and sets its Button text to the text property. when a member of list is gone, it removes the button.
If you need more properties to be remembered (color, size, font, ...) you add them to the class as well. If you need for other controls, as well, .... you can always create common parent controls.
Simple.
If you want to be able to reload it, you could define the MyButton class as serializable and store it in xml file, and upon build, reload it.
You should watch into WPF and it's MVVM pattern. It's pretty much similar to it. Also have a look into command pattern, usefull pattern when it commes to this.
You can remember the FlowLayoutsPanels in one SQL table and in another table you could save the buttons which belong to these FlowLayoutPanels.
On Form Load or Application Load, you could check if there are already FlowLayoutPanels and correspending Buttons do exist in the SQL db and if yes then create them, else do nothing.
I want to get form which is open but hidden. I have tried by this. I get the form but in this case form show and hide within fraction of second. If I skip mfrm.Show(), I don't get MailSynchronize form in Application.OpenForms.
MailSynchronize mfrm = new MailSynchronize();
mfrm.Show();
mfrm.Hide();
I get form by following method.
foreach (Form f in Application.OpenForms) //it will return all the open forms
{
if (f.Name == "MailSynchronize")
{
mfrm = (MailSynchronize)f;
break;
}
}
Can anybody please suggest me how to get open form which is hidden by default and I can get in Application.OpenForms?
If I Hide a form, does it exist in Application.OpenForms?
No, unfortunately if you Hide a form, it will not be present in Application.OpenForms
So how can I open an invisible Form? Also I want it to exists in Application.OpenForms.
If you want to open an invisible Form, and you want it want it to exists in Application.OpenForms, you can use this code instead of simply Show():
var f = new MailSynchronize();
f.Opacity = 0;
f.ShowInTaskbar = false;
f.Show();
How to find that form again?
To get the open instance of form you can use Application.OfType<MailSynchronize>()
var f= Application.OpenForms.OfType<MailSynchronize>()
.FirstOrDefault();
When I found it, How to show it again?
f.Opacity = 1;
f.ShowInTaskbar = true;
f.Show();
How to hide it again?
You should not call Hide() to hide the form because it makes the form to get out of Application.OpenForms, instead you should use this way:
f.Opacity = 0;
f.ShowInTaskbar = false;
Is there another way?
Yes, for example you can create an static property in a class, for example in Program.cs this way:
public static MailSynchronize MailSynchronizeInstance { get; set; }
and the first time you want to open your form, you can assign the instance to this property, and then you can use it using Program.MailSynchronizeInstance to show or hide and you don't need to look in Application.OpenForms or perform a workaround.
Also you can make this property in a singletone way.
EDIT
This should work for your specific case now:
this.Opacity = 0;
this.ShowInTaskbar = false;
When you add these 2 codelines in your MailSynchronize constructor the form will start minimized but will not show in your taskbar, which is essentially the effect you were looking for. Also the form will now popup in your Application.OpenForms Collection.
When form initiallize.
MailSynchronize mfrm = new MailSynchronize();
mfrm.Opacity = 0;
mfrm.Show();
mfrm.Hide();
How to find that form again?
foreach (Form f in Application.OpenForms) //it will return all the open forms
{
if (f.Name == "MailSynchronize")
{
mfrm = (MailSynchronize)f;
break;
}
}
When I found it, How to show it again?
mfrm.Opacity = 1;
mfrm.Show();
Hide again by Button.
mfrm.Hide(); //It will not show form in Application.OpenForms if I hide again by mfrm.Opacity = 0;
use f.Visible (return type is bool)
if it returns false, it means form is hidden. If it returns true then form is visible.
I have my main form and a dialogbox which is called from main. In my main form I have a label and a button that which properties I can't change. I'm using Visual Studio 2015, not sure if there is a bug regarding this. I also made sure my label and button are set to public to modify.
Code: (this is from the dialog box, this has a list box the function is triggered at selectindexchange)
else if ((short)lbDiscountTypes.SelectedValue == 2) //Senior
{
frm_Main main = new frm_Main();
main.VAT = false;
main.labelStatus.Text = "NON-VAT (SENIOR)";
main.labelStatus.BackColor = System.Drawing.Color.IndianRed;
main.labelStatus.ForeColor = System.Drawing.Color.WhiteSmoke;
main.btnNonVat.Enabled = false;
main.btnNonVat.BackColor = System.Drawing.Color.SlateGray;
main.btnNonVat.ForeColor = System.Drawing.Color.Navy;
main.labelVatAmount.Text = 0.00m.ToString();
main.Dispose();
//INQUIRE DISCOUNT TYPES
var Discount = GC.CSHR_DiscountTypes.Where(Filter => Filter.DiscountCode == (short)lbDiscountTypes.SelectedValue);
decimal DP = 0.00m;
foreach (var item in Discount)
{
DP = item.DiscountPercentage;
}
foreach (var item in GC.CSHR_SORepo
.Where(Filter => Filter.Machine == MACHINE
&& Filter.SalesOrderNum == SALESORDERNUM
&& Filter.First_SRP == Filter.IMFSRP))
{
item.DiscountAmount = (item.SoldSRP * DP) / 100;
item.TotalAmount = (item.Quantity * item.SoldSRP) - item.DiscountAmount;
item.VATableSalesOnTotalAmount = (item.Quantity * item.SoldSRP) - item.DiscountAmount;
item.VATRate = 0.00m;
GC.SaveChanges();
}
Close();
}
The code below //INQUIRE DISCOUNT TYPES works well but not the one on top.
I've used debug mode to check if the lines are not being skipped over and they aren't.
You should pay attention to:
You are creating a new instance of your main form that you don't need (while it is open behind the dialog), so you need to get it not create a new instance
You are disposing the main form you created. main.Dispose();
In fact you are creating a new instance of main form and assigning values to those controls and then dispose it. While and instance of yor main form that you expect to see changes on it, is open and untouched behind your dialog.
To set value of those controls you can do one of these ways:
Option 1
Make your labelStatus and btnNonVat public. Open your main form in designer and select labelStatus and btnNonVat and in property grid, set Modifier to public. Then write this code:
//var main = Application.OpenForms.OfType<frm_Main>().FirstOrDefault();
var main = (frm_Main)Application.OpenForms["frm_Main"];
main.labelStatus.Text = "NON-VAT (SENIOR)";
main.labelStatus.BackColor = System.Drawing.Color.IndianRed;
main.labelStatus.ForeColor = System.Drawing.Color.WhiteSmoke;
main.btnNonVat.Enabled = false;
main.btnNonVat.BackColor = System.Drawing.Color.SlateGray;
main.btnNonVat.ForeColor = System.Drawing.Color.Navy;
main.labelVatAmount.Text = 0.00m.ToString();
Option 2
Pass an instance of your frm_Main to your dialog and work with it.
Option 3
After closing the dialog, use values from dialog and set values of your main form
Looks like you are trying to create new form using frm_Main main = new frm_Main(); syntax. All you need to do is get the instance of your current form.
var _currentMainForm= Application.OpenForms[0];
or if you have given name to your form
var _currentMainForm = Application.OpenForms["MainFormName"];
Once you get the reference you can perform all your label updates.
The code on top creates a new form, changes the labels and then disposes the form.
I think you should change the labels of the existing form.
Like in the other answer said you are setting properties of controls into a new Form object and not in the form where you come from.
You should pass the form object into the parameters of the dialog, something like:
void myDialog(frm_Main callingForm)
{
callingForm.Textbox1.Text = "abc";
}
And call it from you main form like this
...
myDialog(this);
I have a main form in a panel on the left thats clickable, depending on what you click a new type of form opens. on the righti have another panel where i want to dock the forms that have been opened from clicking on the left.
How can i get the forms to add in a list under one another in the panel on the right? the issue with the code below is that it adds the first element fine. However when i add the second element they both dissapear behind the panel :/
private void addToPanel2(Form o)
{
if (o is Form)
{
if (panel2.Controls.Count == 0)
{
o.MdiParent = this;
panel2.Controls.Add(o);
o.Dock = DockStyle.Top;
o.Show();
}
else
{
//then we know that this is an addable data item
foreach (Form obj in panel2.Controls)
{
if(obj.GetType().Name.Equals(o.GetType().Name))
{
//we dont want to add it as the data type is already open
MessageBox.Show("This data item must already be open. Please Check.");
}
else
{
// add it as its not in there
Form f = (Form)obj;
f.MdiParent = this;
f.Dock = DockStyle.Top;
f.Show();
}
}
}
}
thanks
This is not possible, an MDI child form cannot be a child control of a panel. Adding a non-MDI form to a panel is an iffy proposition as well but is supported. Call its SetTopLevel() method, passing false, set its Visible property to true. You also have to set its FormBorderStyle property to None, it no longer behaves properly as a top-level window.
This just turns it into a UserControl. You are better off actually making it a UserControl, that uses a lot less resources and is much better documented.