Basically, i am creating a raw-based web browser application. Bookmarks are added in contextmenu toolstripitem either from using "star" button or via another form. When added using another form, it is not refreshing the contextmenu items which are added from another form in the main form.
MainForm View:
mainform
Favourites/Bookmarks View:
bookmarks
updatebookmarks
This is how it is added via another form:
addbookmark
addbookmark2
Code Preview:
Star Button:
private void favButton_Click(object sender, EventArgs e)
{
if(inputUrlBox.Text != "")
{
var item = inputUrlBox.Text.ToString();
if(!favouritesToolStripMenuItem.DropDownItems.Cast<ToolStripMenuItem>().Any(x => x.Text == item))
{
try {
Properties.Settings.Default.BookmarksList.Add(item + ",null");
Properties.Settings.Default.Save();
foreach (var bookmark in Properties.Settings.Default.BookmarksList) {
var link = bookmark.Split(',')[0].ToString();
favouritesToolStripMenuItem.DropDownItems.Add(link);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
else
{
MessageBox.Show("Bookmark already exists!");
}
}
}
Moving directly to "Add" in another form's button (this is written in BookmarkWindow Form):
private void addButton_Click(object sender, EventArgs e)
{
AddBookmarkWindow form = new AddBookmarkWindow();
form.ShowDialog(this);
}
In AddBookMark's Form (AddBookmkarkWindow.cs):
if ((isUri) && (linkinput != null && linkinput.Length > 0) && (nameinput != null && nameinput.Length > 0))
{
Properties.Settings.Default.BookmarksList.Add(linkinput + "," + nameinput);
Properties.Settings.Default.Save();
MainWindow mw = new MainWindow();
mw.updatebookmarkstab(linkinput);
this.Close();
MessageBox.Show("Added!");
}
This "updatebookmarkstab" function is in mainwindow/mainform:
public void updatebookmarkstab(string item)
{
menuStrip1.Refresh();
contextMenuStrip1.Refresh();
favouritesToolStripMenuItem.DropDownItems.Add(item);
}
What I expect is, once i add bookmark(s) from another form, I want it to be showed in main form's contextmenustrip item just like how "star" works.
Anyone has any idea on how to refresh menuitems from another form or has a better solution to provide this view.
Related
Within my application i am trying to use forms in tabpages. These forms are all data managing forms.
I edited the tabcontrol (created a custom tabcontrol) so i can remove tabpages by double clicking on the tabheader.
protected override void OnMouseDoubleClick(MouseEventArgs e)
{
base.OnMouseDoubleClick(e);
//* Default method of closing a tab.
if (Selectedtab != null)
TabPages.Remove(Selectedtab);
}
Although it works. Its actually not doing what I need.
Because any changes on the form in the tabpage, are lost, regardless of the below
public partial class SomeForm : Form
{
private void SomeForm_FormClosing(object sender, FormClosingEventArgs e)
{
if (HasChanges() && CustomMessage.WarningBox("There is unsaved data. Are you sure you want to close"))
return;
((TabControl)((TabPage)this.Parent).Parent).TabPages.Remove((TabPage)this.Parent);
}
}
When setting a breakpoint at this function, it never enters.
Now my question: Is it possible to call the Close method of the form from Tabcontrol. Preferably something like below.
protected override void OnMouseDoubleClick(MouseEventArgs e)
{
base.OnMouseDoubleClick(e);
if (Selectedtab != null)
{
if (Selectedtab.EmbeddedForm != null)
TabPages.ASelectedtab.EmbeddedForm.Close();
}
}
The main problem I am facing is I don't know how to access a function on a form from only knowing the selected tab. And I cant find it either.
Solution after using KyleWangs answer as base:
Custom Control:
protected override void OnMouseDoubleClick(MouseEventArgs e)
{
base.OnMouseDoubleClick(e);
string frmSearchName = "Frm" + SelectedTab.Name.Substring(3);
Form f = (Form)Application.OpenForms[frmSearchName];
if (f != null)
f.Close();
else
TabPages.Remove(SelectedTab);
}
Form:
private void SomeForm_FormClosing(object sender, FormClosingEventArgs e)
{
SetChanges();
if (HasChanges() && !CustomMessage.WarningBox("There is unsaved data. Are you sure you want to close?"))
e.Cancel = true;
else
((TabControl)((TabPage)this.Parent).Parent).TabPages.Remove((TabPage)this.Parent);
}
You can use property Application.OpenForms to get the open form instance.
private void Form1_Load(object sender, EventArgs e)
{
tabControl1.TabPages.Clear();
PageForm1 f1 = new PageForm1();
AddNewTab(f1);
}
private void AddNewTab(Form frm)
{
TabPage tab = new TabPage(frm.Text);
frm.TopLevel = false;
frm.Parent = tab;
frm.Visible = true;
tabControl1.TabPages.Add(tab);
frm.Location = new Point((tab.Width - frm.Width) / 2, (tab.Height - frm.Height) / 2);
tabControl1.SelectedTab = tab;
}
private void tabControl1_DoubleClick(object sender, EventArgs e)
{
Form f = (Form)Application.OpenForms[tabControl1.SelectedTab.Text];
f.Close();
tabControl1.TabPages.RemoveAt(tabControl1.SelectedIndex);
}
I have a tool strip menu in my parent form and I'm loading my child forms into a panel as user controls. I need to fire an event in my child form when the user clicks on the menu strip in my parent form.
Here is the event in the parent control:
//Character Name
private void randomNameToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
if (_SQL_Settings.TabControl == "Character Builder")
{
}
else
{
MessageBox.Show("You must be in the Character Builder Screen
To Generate A Random Character Name, Please Try Again.");
}
}
catch(Exception ex)
{
}
}
//Character
private void randToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
if (_SQL_Settings.TabControl == "Character Builder")
{
}
else
{
MessageBox.Show("You must be in the Character Builder Screen
To Generate A Random Character, Please Try Again.");
}
}
catch (Exception ex)
{
}
}
Here is where I Build my child form in the Parent form:
case "Character Builder":
{
Character_Builder CC = new Character_Builder();
panCC.Controls.Clear();
CC.Dock = DockStyle.Fill;
panCC.Controls.Add(CC);
CC.Main_Menu += Main_Menu;
break;
}
And here is the functions I want to fire off when the user clicks on the parent form menu strip items
private void Generate_Raondom_Character()
{
try
{
}
catch(Exception ex)
{
}
}
private void Generate_Random_Character_Name()
{
try
{
}
catch (Exception ex)
{
}
}
I have added these two events in my child form but I think they need to be in my parent form.
Events:
public event EventHandler Random_Character;
public event EventHandler Random_Name;
Does anyone know what I need to do to get this to work? Sample would be great. I know how to do it in Vb just not c#.
I have one solution. This is not what I wanted to do but it seems to work. I am looping through the controls in my child forum until I find the control I want and editing the controls text. I wanted to use events but I guess this works too. If anyone has better ways to do this please share:
if (_SQL_Settings.TabControl == "Character Builder")
{
DataTable dt = new DataTable();
dt = _SQL.Random_Character_Name();
foreach (Control Parentctrl in panCC.Controls)
{
if (Parentctrl.Name == "Character_Builder")
{
foreach (Control Childctrl in Parentctrl.Controls)
{
if (Childctrl.Name == "cbFirstName")
{
Childctrl.Text = dt.Rows[0]["First_Name"].ToString();
}
if (Childctrl.Name == "cbLastName")
{
Childctrl.Text = dt.Rows[0]["Last_Name"].ToString();
}
if (Childctrl.Name == "cbCharacterTitle")
{
Childctrl.Text = dt.Rows[0]["Character_Title"].ToString();
}
}
}
}
I have a method that I use the open a Mid Child.
Lets say I am on a form called "InventoryAdd" on this form I have a drop down menu. When a user selects a value "-1" from the menu, I want to open another (ie. DepartmentsAdd().) Then after DepartmentAdd open I want to close InventoryAdd form.
this is the code behind the menu on InventoryAdd form
private void InputDepartment_SelectedValueChanged(object sender, EventArgs e) {
//InputDepartment.ValueMember = "ID";
int selectedDept = Convert.ToInt32(InputDepartment.SelectedValue);
if (selectedDept == -1) {
Form myForm = this.ActiveMdiChild;
Common.OpenMyForm("Vendors", new string[] { "add" }, new DepartmentsAdd());
if (myForm != null) {
myForm.Close();
}
}
}
This method what opens the new Mid form
public static void OpenMyForm(string sectionName, string[] keys, Form myform) {
//make sure there are no other forms of the ame type open
foreach (Form form in Application.OpenForms) {
if (form.GetType() == myform.GetType()) {
form.Activate();
return;
}
}
if (Settings._AuthenticationMode == "Thumbprint") {
var newMDIChild = myform;
// Set the Parent Form of the Child window.
newMDIChild.MdiParent = AppContext.CurrentContext.MainForm;
// Display the new form.
newMDIChild.Show();
}
if (Settings._AuthenticationMode == "Single" && UserInfo.Autherized == true) {
var role = new Roles();
if (role.hasAccess(sectionName, keys)) {
var newMDIChild = myform;
// Set the Parent Form of the Child window.
newMDIChild.MdiParent = AppContext.CurrentContext.MainForm;
// Display the new form.
newMDIChild.Show();
}
else {
Common.Alert("You do not have a permissions to perform this action!");
}
}
}
}
My code open the Mid form with no issues. However, the "InventoryAdd" form never close. "myForm" is always null to it never close it.
How can I properly close the Mid form?
Thanks
If you set an event listener for shown on the newly opened form in the calling context you can have the existing form close itself once its child is opened.
Form myForm=new Form();
myForm.shown += closeForm;
...
void closeForm(object sender, EventArgs e){
this.Dispose(); // as long as within the previous forms context.
}
myForm.Close();
is closing the program try to use
myForm.Hide();
I am developing a C# Windows Forms application. I would like to have a single instance of all the forms.
So, when the user clicks on the Contact button, for instance, twice, instead of having two contact forms, I would to bring the single instance contact form to the front.
How can I achieve this?
Check if the form exists in collection of open forms before creating and showing the form using Application.OpenForms
if (System.Windows.Forms.Application.OpenForms["Form1"] as Form1 != null)
MessageBox.Show("Form1 is opened");
else
MessageBox.Show("Form1 is not opened");
public static Form GetOpenedForm<T>() where T: Form {
foreach (Form openForm in Application.OpenForms) {
if (openForm.GetType() == typeof(T)) {
return openForm;
}
}
return null;
}
And in your code, where you create the ContactForm:
ContactForm form = (ContactForm) GetOpenedForm<ContactForm>();
if (form == null) {
form = new ContactForm();
form.Show();
} else {
form.Select();
}
Simple as that:
Form fc = Application.OpenForms["Form1"];
if (fc != null)
{
fc.Focus();
}
else
{
Form1 f1 = new Form1();
f1.Show();
}
You can disable the contactButton when it is clicked and open the contactForm-
private void contactButton_Click(object sender, EventArgs e)
{
contactButton.Enabled=false;
//code to open the contactForm
}
When the contactForm is closed, you can re-enable the button-
contactButton.Enabled=true;
Try this combo
First make contact form a global object
private ContactForm contactForm;
Then your contact button handler:
private void contactButton_Click(object sender, EventArgs e)
{
if (contactForm == null)
{
contactForm = new ContactForm();
contactForm.FormClosing += new FormClosingEventHandler(contactForm_FormClosing);
}
contactForm.Show();
}
Then handle the FormClosing event of the ContactForm to hide it rather than close it:
private void contactForm_FormClosing(object sender, FormClosingEventArgs e)
{
contactForm.Hide();
e.Cancel = true;
}
Or if you want the contact form to close, and open as new next time, handle the FormClosed instead:
private void contactForm_FormClosed(object sender, FormClosedEventArgs e)
{
contactForm = null;
}
Then next time the button is clicked, the null if clause will be caught and the form will be set to a new instance and opened.
Form2 form2 = null;
private void button1_Click(object sender, EventArgs e)
{
bool isFormExists = false;
foreach (Form openForm in Application.OpenForms)
{
if (openForm == form2 && openForm!=null)
{
openForm.Focus();
isFormExists = true;
break;
}
}
if (!isFormExists)
{
form2 = new Form2();
form2.Show();
}
}
I'd go with Otiel's answer. Also you can add a WindowState, because if the form is minimized it won't be shown. this answer can be used to get the restore method.
ContactForm form = (ContactForm) GetOpenedForm<ContactForm>();
if (form == null) {
form = new ContactForm();
form.Show();
} else {
//use this (if you want it to be restored to normal and focused)
//no need of extension method
//form.WindowState = FormWindowState.Normal;
//form.Select();
//or use this if you want it to be restored as previous state and focused
//You need a Restore extension method that can be found in the link above
form.Focus();
form.Restore();
}
I have a 'loader app' that loads a menu and when user clicks the menu image button a list view opens based on the text
(if text = employee)
(Go to class A)
(Go to class B)
...
...
(Show List View Window)
if he clicks again on the same button it opens again, I would like to prevent this.
i.e but this for a WPF application
If you want a list of the open forms, that is Application.OpenForms. You could iterate over this, using GetType() and checking the .Assembly to find those from a different assembly. Beyond that, I'm not entire clear on the question...
Assembly currentAssembly = Assembly.GetExecutingAssembly();
List<Form> formsFromOtherAssemblies = new List<Form>();
foreach (Form form in Application.OpenForms) {
if (form.GetType().Assembly != currentAssembly) {
formsFromOtherAssemblies.Add(form);
}
}
If you just want to track forms you have opened yourself, then cache that instance. Or if you use "owned forms", you can just check by name:
private void button1_Click(object sender, EventArgs e) {
foreach (Form form in OwnedForms) {
if (form.Name == "Whatever") {
form.Activate();
return;
}
}
Form child = new Form();
child.Name = "Whatever";
child.Owner = this;
child.Show(this);
}
NewProduct newproduct;
private void button1_Click(object sender, EventArgs e)
{
if(!isOpened())
{
newproduct = new NewProduct();
newproduct.Show();
}
}
private bool isOpened()
{
foreach (Form f in Application.OpenForms)
{
if (f == newproduct)
{
return true;
}
}
return false;
}
Another simple example
private Boolean FindForm(String formName)
{
foreach (Form f in Application.OpenForms)
{
if (f.Name.Equals(formName))
{
f.Location = new Point(POINT.X, POINT.Y + 22);
return true;
}
}
return false;
}
You can use a Command pattern. The loader assembly will search for commands in loaded assemblies.
For every command the loader create menu item ( or anything else, you want ), and click event will run the concrete command.
The command must know if should be created new form or used some already existing.
Mark Garvell's answer helped me to figure out what I should do, but it needed adjusting for WPF.
(In my case I wanted to close any windows not owned by the main one when it closes, but the principle is the same.)
private void EmployeeMenuItemClick(object sender, RoutedEventArgs e)
{
bool found = false;
foreach(Window w in Application.Current.Windows)
{
if(w.GetType() == typeof(EmployeeListViewWindow)
{
found = true;
break;
}
}
if(!found)
{
EmployeeListViewWindow ew = new EmployeeListViewWindow();
ew.Show();
}
}