C
C#2y ago
Whiteboy

Enable button from another Form [Answered]

there is -Main menu then 3 subforms to main menu -A, B, C I want to enable Main Menu button when i click a button in form A or B or C and the code that moves user through forms
private void OpenChildForm(Form childForm, object btnSender)
{
if (btnSender is null)
{
throw new ArgumentNullException(nameof(btnSender));
}

_activeForm?.Close();

_activeForm = childForm;
childForm.TopLevel = false;
childForm.FormBorderStyle = FormBorderStyle.None;
childForm.Dock = DockStyle.Fill;
this.panelDesktop.Controls.Add(childForm);
this.panelDesktop.Tag = childForm;
childForm.BringToFront();
childForm.Show();
}
private void OpenChildForm(Form childForm, object btnSender)
{
if (btnSender is null)
{
throw new ArgumentNullException(nameof(btnSender));
}

_activeForm?.Close();

_activeForm = childForm;
childForm.TopLevel = false;
childForm.FormBorderStyle = FormBorderStyle.None;
childForm.Dock = DockStyle.Fill;
this.panelDesktop.Controls.Add(childForm);
this.panelDesktop.Tag = childForm;
childForm.BringToFront();
childForm.Show();
}
104 Replies
TheRanger
TheRanger2y ago
first you need to have a reference of your Main Menu form in your child forms
Whiteboy
Whiteboy2y ago
well is it gonna be a problem if it's opposite?
TheRanger
TheRanger2y ago
what do u mean?
Whiteboy
Whiteboy2y ago
the menu is a reference to subforms like this is menu
Whiteboy
Whiteboy2y ago
Whiteboy
Whiteboy2y ago
and these buttons take you to forms A B C so just the right side changes and the left with buttons is always the same no matter in which form you are
TheRanger
TheRanger2y ago
yea you can atleast pass a reference of your main form to ur child form through a method
private void OpenChildForm(Form childForm, object btnSender)
{
if (btnSender is null)
{
throw new ArgumentNullException(nameof(btnSender));
}

_activeForm?.Close();

_activeForm = childForm;
childForm.TopLevel = false;
childForm.FormBorderStyle = FormBorderStyle.None;
childForm.Dock = DockStyle.Fill;
this.panelDesktop.Controls.Add(childForm);
this.panelDesktop.Tag = childForm;
childForm.BringToFront();
childForm.Show();
if (childForm is A a)
{
a.Foo(this);
}
}
private void OpenChildForm(Form childForm, object btnSender)
{
if (btnSender is null)
{
throw new ArgumentNullException(nameof(btnSender));
}

_activeForm?.Close();

_activeForm = childForm;
childForm.TopLevel = false;
childForm.FormBorderStyle = FormBorderStyle.None;
childForm.Dock = DockStyle.Fill;
this.panelDesktop.Controls.Add(childForm);
this.panelDesktop.Tag = childForm;
childForm.BringToFront();
childForm.Show();
if (childForm is A a)
{
a.Foo(this);
}
}
u can do whatever this method needs to do, like enabling a button
Whiteboy
Whiteboy2y ago
oh so it's that simple
TheRanger
TheRanger2y ago
yes, u can make the method take the argument and assign it to a field of type MainMenuForm or whatever you called it then in whatever button you want to click in your childform, just do the logic to enable the Main Menu Button
//
// your child form
//
private MainMenuForm _mainMenu; // your field
Foo(MainMenuForm mainMenu)
{
_mainMenu = mainMenu;
}

private void Button1_Clicked(object sender, EventArgs e)
{
_mainMenu.EnableYourButton();
}
//
// your child form
//
private MainMenuForm _mainMenu; // your field
Foo(MainMenuForm mainMenu)
{
_mainMenu = mainMenu;
}

private void Button1_Clicked(object sender, EventArgs e)
{
_mainMenu.EnableYourButton();
}
looks like you call it Form1, so lemme juste dit
Whiteboy
Whiteboy2y ago
it's actually myMain i f up some names there
TheRanger
TheRanger2y ago
it would get ugly if you repeat the same code i wrote on the 3 forms so let the 3 forms atleast inherit from another form that has the logic
Whiteboy
Whiteboy2y ago
i nee to fix the naming 1st XD Error CS0122 'MainMenu.btnUpgrade' is inaccessible due to its protection level so the button needs public modifiers?
TheRanger
TheRanger2y ago
never make field public just define a public property that returns that field its not recommended to access a button from another class, better define a method and call it something like EnableMainMenuButton
Whiteboy
Whiteboy2y ago
same error
TheRanger
TheRanger2y ago
let me edit the post above can you show what you wrote? is your method public?
Whiteboy
Whiteboy2y ago
private void OpenChildForm(Form childForm, object btnSender)
{
if (btnSender is null)
{
throw new ArgumentNullException(nameof(btnSender));
}

_activeForm?.Close();

_activeForm = childForm;
childForm.TopLevel = false;
childForm.FormBorderStyle = FormBorderStyle.None;
childForm.Dock = DockStyle.Fill;
this.panelDesktop.Controls.Add(childForm);
this.panelDesktop.Tag = childForm;
childForm.BringToFront();
childForm.Show();

if (childForm is ItemSelectionMenu itemselectmenu)
{
itemselectmenu.EnableButtons(this);
}
}
private void OpenChildForm(Form childForm, object btnSender)
{
if (btnSender is null)
{
throw new ArgumentNullException(nameof(btnSender));
}

_activeForm?.Close();

_activeForm = childForm;
childForm.TopLevel = false;
childForm.FormBorderStyle = FormBorderStyle.None;
childForm.Dock = DockStyle.Fill;
this.panelDesktop.Controls.Add(childForm);
this.panelDesktop.Tag = childForm;
childForm.BringToFront();
childForm.Show();

if (childForm is ItemSelectionMenu itemselectmenu)
{
itemselectmenu.EnableButtons(this);
}
}
and the child form
TheRanger
TheRanger2y ago
the 3 forms inherit from ItemSelectionMenu right?
Whiteboy
Whiteboy2y ago
private MainMenu _mainMenu;

public void EnableMainMenuBtn()
{
_mainMenu.btnUpgrade.Enabled = true;
}
private MainMenu _mainMenu;

public void EnableMainMenuBtn()
{
_mainMenu.btnUpgrade.Enabled = true;
}
yea w8 no from main menu
TheRanger
TheRanger2y ago
the MainMenu is the one who should have the method
Whiteboy
Whiteboy2y ago
main menu is like background form with just the 3 button on the left
TheRanger
TheRanger2y ago
private MainMenu _mainMenu;

public void EnableMainMenuBtn()
{
_mainMenu.EnableBtnUpgrade();
}
private MainMenu _mainMenu;

public void EnableMainMenuBtn()
{
_mainMenu.EnableBtnUpgrade();
}
because only the MainMenu class can access its private members you cannot access a private member from another class what class do the child forms inherit from?
Whiteboy
Whiteboy2y ago
MainMenu
TheRanger
TheRanger2y ago
why would you do that?
Whiteboy
Whiteboy2y ago
i don't want the user to be albe to go anywhere he has to go to 1st menu then 2nd then 3rd
TheRanger
TheRanger2y ago
what do u mean?
Whiteboy
Whiteboy2y ago
Whiteboy
Whiteboy2y ago
so you have to go to Item Selection and select item then you can go Upgrade it
TheRanger
TheRanger2y ago
this wont work
if (childForm is ItemSelectionMenu itemselectmenu)
{
itemselectmenu.EnableButtons(this);
}
if (childForm is ItemSelectionMenu itemselectmenu)
{
itemselectmenu.EnableButtons(this);
}
since childform is not a type of ItemSelectionMenu, or does not extend it
Whiteboy
Whiteboy2y ago
and only then u can go to rarity
TheRanger
TheRanger2y ago
the is operator returns true when the type of the provided variable is of that type, or inherits from it and if its true, it will create a new variable of type ItemSelectionMenu called itemselectmenu and assigns the value from childForm to it what are you doing anyway, a game?
Whiteboy
Whiteboy2y ago
i wanted at first but then decided just to do some 4fun upgrade simulation i need anything on github that proves that i do like anything connected to coding to even get an internship or sth my 3rd year of college starts soon D: and we learned basically nothing there what i learned from doing this app is like 10x more than in college
TheRanger
TheRanger2y ago
cool
Whiteboy
Whiteboy2y ago
so i passed a boolean through other class menu but nto i need to click the button again to refresh it so button upgrade enables
private void BtnViewStats_Click(object sender, EventArgs e)
{
tbItemStats.Text = null;
btnRollValues.Enabled = true;

if (sender is not Button button) return;
var toolTip = new ToolTip();
var caption = Equipment.Equipments[button.Name];

btnRollValues.Name = button.Name;
toolTip.SetToolTip(tbItemStats, caption.ToString());
tbItemStats.Text = caption.ToString();
button.BackColor = Color.Blue;

SharedClass.ImageToDisplay = button.Image;
SharedClass.UpgradeLvlValue = Equipment.Equipments[button.Name];
SharedClass.RarityLvlValue = Equipment.Equipments[button.Name];
SharedClass.ItemId = button.Name;
SharedClass.BtnEnable = true;
}
private void BtnViewStats_Click(object sender, EventArgs e)
{
tbItemStats.Text = null;
btnRollValues.Enabled = true;

if (sender is not Button button) return;
var toolTip = new ToolTip();
var caption = Equipment.Equipments[button.Name];

btnRollValues.Name = button.Name;
toolTip.SetToolTip(tbItemStats, caption.ToString());
tbItemStats.Text = caption.ToString();
button.BackColor = Color.Blue;

SharedClass.ImageToDisplay = button.Image;
SharedClass.UpgradeLvlValue = Equipment.Equipments[button.Name];
SharedClass.RarityLvlValue = Equipment.Equipments[button.Name];
SharedClass.ItemId = button.Name;
SharedClass.BtnEnable = true;
}
this is the button that should enable the menu button Upgrade
private void EnableButtons()
{
btnUpgrade.Enabled = SharedClass.BtnEnable;
}
private void EnableButtons()
{
btnUpgrade.Enabled = SharedClass.BtnEnable;
}
public static bool BtnEnable { get; set; }
public static bool BtnEnable { get; set; }
TheRanger
TheRanger2y ago
its a private method, so u cant access it outside its class
Whiteboy
Whiteboy2y ago
ah yes nvm i tought it worked then it crashed the app Error CS0120 An object reference is required for the non-static field, method, or property 'MainMenu.EnableButtons()'
TheRanger
TheRanger2y ago
what is MainMenu anyway
Whiteboy
Whiteboy2y ago
a form
TheRanger
TheRanger2y ago
Form1 or the sidebar with the 3 buttons on the left?
Whiteboy
Whiteboy2y ago
form1 it's sidebar + background for other forms
TheRanger
TheRanger2y ago
you need a reference of your current MainMenu instance ur accessing EnableButtons as if its a static method, when it isnt even if you did make it static, you can't access its controls because they are not static
Whiteboy
Whiteboy2y ago
how do i do that reference
TheRanger
TheRanger2y ago
what did you try? where are u trying to call EnableButtons anyway? because i feel ur just copying code without understanding it
Whiteboy
Whiteboy2y ago
in the button that should enable it
TheRanger
TheRanger2y ago
in which class?
Whiteboy
Whiteboy2y ago
ItemSelectionMenu.cs
TheRanger
TheRanger2y ago
can you show code? thats not really a class, thats just a file name
Whiteboy
Whiteboy2y ago
private void BtnViewStats_Click(object sender, EventArgs e)
{
tbItemStats.Text = null;
btnRollValues.Enabled = true;

if (sender is not Button button) return;
var toolTip = new ToolTip();
var caption = Equipment.Equipments[button.Name];

btnRollValues.Name = button.Name;
toolTip.SetToolTip(tbItemStats, caption.ToString());
tbItemStats.Text = caption.ToString();
button.BackColor = Color.Blue;

SharedClass.ImageToDisplay = button.Image;
SharedClass.UpgradeLvlValue = Equipment.Equipments[button.Name];
SharedClass.RarityLvlValue = Equipment.Equipments[button.Name];
SharedClass.ItemId = button.Name;
SharedClass.BtnEnable = true;
MainMenu.EnableButtons();
}
private void BtnViewStats_Click(object sender, EventArgs e)
{
tbItemStats.Text = null;
btnRollValues.Enabled = true;

if (sender is not Button button) return;
var toolTip = new ToolTip();
var caption = Equipment.Equipments[button.Name];

btnRollValues.Name = button.Name;
toolTip.SetToolTip(tbItemStats, caption.ToString());
tbItemStats.Text = caption.ToString();
button.BackColor = Color.Blue;

SharedClass.ImageToDisplay = button.Image;
SharedClass.UpgradeLvlValue = Equipment.Equipments[button.Name];
SharedClass.RarityLvlValue = Equipment.Equipments[button.Name];
SharedClass.ItemId = button.Name;
SharedClass.BtnEnable = true;
MainMenu.EnableButtons();
}
TheRanger
TheRanger2y ago
a file can contain many classes a file's name can even be different from the class name defined inside the file
Whiteboy
Whiteboy2y ago
yeah buti keep it simple new class = new file
TheRanger
TheRanger2y ago
EnableButtons isnt a static method and u cant make it static because forms arent static
Whiteboy
Whiteboy2y ago
yeah i understand that
TheRanger
TheRanger2y ago
you need a reference of your MainMenu instance assigned in a field of your class _mainMenu.EnableButtons(); for example will call the method from the instance of your current MainMenu that is assigned in _mainMenu
MKP
MKP2y ago
I typically do this too, unless I need Extension methods on an enum Or its a factory
TheRanger
TheRanger2y ago
but then you need to figure out how to assign the reference of your current MainMenu instance to your field
Whiteboy
Whiteboy2y ago
im too green to even understand what u just said so i have this field in UpgradeMenu private MainMenu _mainMenu; and this is the method in Main Menu
public void EnableButtons()
{
btnUpgrade.Enabled = SharedClass.BtnEnable;
}
public void EnableButtons()
{
btnUpgrade.Enabled = SharedClass.BtnEnable;
}
but when i run it i get "object reference not se to an object"
MKP
MKP2y ago
enum ABC
{
A = 1,
B = 2,
C = 3
}

static class ABCExtensions
{
public static double Half(this ABC example) => ((double) example) / 2.0;
}

ABC.B.Half() == 1
enum ABC
{
A = 1,
B = 2,
C = 3
}

static class ABCExtensions
{
public static double Half(this ABC example) => ((double) example) / 2.0;
}

ABC.B.Half() == 1
TheRanger
TheRanger2y ago
because your field is null
Whiteboy
Whiteboy2y ago
TheRanger
TheRanger2y ago
its null, it has no value you need to find a reference of your current MainMenu Form and assign to it
MKP
MKP2y ago
Probably by passing this through a constructor
TheRanger
TheRanger2y ago
how? you can either pass through a method, through a constructor, or any other many ways you can pass through the constructor, the recommended way
Whiteboy
Whiteboy2y ago
public ItemSelectionMenu(MainMenu mainMenu)
{
_mainMenu = mainMenu;
}
public ItemSelectionMenu(MainMenu mainMenu)
{
_mainMenu = mainMenu;
}
so i have the constructor
TheRanger
TheRanger2y ago
yeah that
Whiteboy
Whiteboy2y ago
and it should be where it is in ItemSelectMenu not main menu right?
TheRanger
TheRanger2y ago
if you are calling new ItemSelectMenu from your MainMenu use new ItemSelectMenu(this) where this is a reference to your current MainMenu instance
Whiteboy
Whiteboy2y ago
but i am not? ;-;
TheRanger
TheRanger2y ago
where are you calling it?
Whiteboy
Whiteboy2y ago
i don't quite understand your question
private void OpenChildForm(Form childForm, object btnSender)
{
if (btnSender is null)
{
throw new ArgumentNullException(nameof(btnSender));
}

_activeForm?.Close();

_activeForm = childForm;
childForm.TopLevel = false;
childForm.FormBorderStyle = FormBorderStyle.None;
childForm.Dock = DockStyle.Fill;
panelDesktop.Controls.Add(childForm);
panelDesktop.Tag = childForm;
childForm.BringToFront();
childForm.Show();
}
private void OpenChildForm(Form childForm, object btnSender)
{
if (btnSender is null)
{
throw new ArgumentNullException(nameof(btnSender));
}

_activeForm?.Close();

_activeForm = childForm;
childForm.TopLevel = false;
childForm.FormBorderStyle = FormBorderStyle.None;
childForm.Dock = DockStyle.Fill;
panelDesktop.Controls.Add(childForm);
panelDesktop.Tag = childForm;
childForm.BringToFront();
childForm.Show();
}
this is how i open another forms
TheRanger
TheRanger2y ago
yes but where are u calling OpenChildForm
Whiteboy
Whiteboy2y ago
private void BtnItemSelect_Click(object sender, EventArgs e)
{
btnItemSelect.Image = Image.FromFile(@"")
OpenChildForm(new ItemSelectionMenu(), sender);
}
private void BtnItemSelect_Click(object sender, EventArgs e)
{
btnItemSelect.Image = Image.FromFile(@"")
OpenChildForm(new ItemSelectionMenu(), sender);
}
TheRanger
TheRanger2y ago
there it is where is this defined?
Whiteboy
Whiteboy2y ago
in MainMenu
TheRanger
TheRanger2y ago
exactly so do
OpenChildForm(new ItemSelectionMenu(this), sender);
OpenChildForm(new ItemSelectionMenu(this), sender);
Whiteboy
Whiteboy2y ago
Whiteboy
Whiteboy2y ago
this is not what i expected XD
TheRanger
TheRanger2y ago
what is?
Whiteboy
Whiteboy2y ago
i clicked the button
TheRanger
TheRanger2y ago
what button
Whiteboy
Whiteboy2y ago
this
TheRanger
TheRanger2y ago
weird, did u change something? other than passing the reference of ur mainmenu to ur constructor
Whiteboy
Whiteboy2y ago
hmm
public void EnableButtons()
{
btnUpgrade.Enabled = true;
}
public void EnableButtons()
{
btnUpgrade.Enabled = true;
}
this in main menu the constructor is the same nah i don't know
TheRanger
TheRanger2y ago
what is btnUpgrade
Whiteboy
Whiteboy2y ago
the button that i want to enable
TheRanger
TheRanger2y ago
comment btnUpgrade.Enabled = true; and see what happens //btnUpgrade.Enabled = true;
Whiteboy
Whiteboy2y ago
same thing goes blank
TheRanger
TheRanger2y ago
issue is somewhere else probably
Whiteboy
Whiteboy2y ago
i removed "this" from the call of OpenChildForm and it doesn't go blank
TheRanger
TheRanger2y ago
ah then you have 2 constructors in your ItemSelectionMenu() the other one initializes your components
Whiteboy
Whiteboy2y ago
ah yea
TheRanger
TheRanger2y ago
you should only have 1 constructor
Whiteboy
Whiteboy2y ago
TheRanger
TheRanger2y ago
yes, InitializeComponent method needs to be called the other constructor doesnt
Whiteboy
Whiteboy2y ago
ayy works as it should
TheRanger
TheRanger2y ago
and ur btnUpgrade got enabled?
Whiteboy
Whiteboy2y ago
yes
TheRanger
TheRanger2y ago
cool
Whiteboy
Whiteboy2y ago
thank you so in the end error was two same constructors xD
Accord
Accord2y ago
✅ This post has been marked as answered!
TheRanger
TheRanger2y ago
those 2 constructors arent the same
Whiteboy
Whiteboy2y ago
well yes but it this caused error because the OpenChildForm never called the 1st one
TheRanger
TheRanger2y ago
1 constructor can inherit from another
Whiteboy
Whiteboy2y ago
or didn't call InitializeComponent() so menu never loaded
TheRanger
TheRanger2y ago
public ItemSelectionMenu(MainMenu mainMenu) : this() this will call the other constructor first then calls its own in case you want to add more logic that you dont want to repeat in the other
Whiteboy
Whiteboy2y ago
makes sense ty again