I have a checkbox in form1, when it is checked it makes a PictureBox in form2 visible but when I uncheck I want to refresh form2 so that the PictureBox is not visible. This code is in form1. It is a button that opens up the form if one if not open but if a form is open it refreshes it. The problem is that it is not refreshing. Can anyone tell me what is wrong?
private tuesday _FavoritesForm;
public void startbutton_Click(object sender, EventArgs e)
{
if (_FavoritesForm == null)
{
_FavoritesForm = new tuesday();
_FavoritesForm.Closed += new EventHandler(_FavoritesForm_Closed);
_FavoritesForm.Show();
}
else
{
_FavoritesForm.Refresh();
}
}
Calling Refresh on a form merely forces it to be repainted. There isn't any reason to assume that it will repaint differently. You would have to override the OnPaint() method in that form. Clearly you are not using OnPaint to draw an image, you are using a PictureBox. Setting that control's Visible property to false will make the image disappear, no additional help is needed.
I would add a public method on the secondary form to Show/Hide the picture because it appears the second form has no idea of the first form. Then the click / checkbox setting on the first form to instead of doing a "REFRESH" on the second, create the form if its not already done so. Once created, call whatever method you expose on the secondary form to specifically make visible or not as needed.
EDIT FOR CLARIFICATION
#a13xy, actually the reverse... The second form has no idea of the first, but yes, have a method that is public on the 2nd. Then on the FIRST form, in the click / value changed event of your checkbox, you just call the method from that... such as your sample code...
public void startbutton_Click(object sender, EventArgs e)
{
if (_FavoritesForm == null)
{ _FavoritesForm = new tuesday();
_FavoritesForm.Closed += new EventHandler(_FavoritesForm_Closed);
_FavoritesForm.Show();
}
else
{ _FavoritesForm.Refresh();
}
_FavoritesForm.ShowHide( IsCurrentForms.CheckBox.IsCheckedValue );
}
Not positive of your checkbox controls name, or its Checked value property, just call the second form's method directly with whatever your forms value is and the method in the SECOND form could be something like...
public void ShowHide( Boolean ShowTheImage )
{
// value provided as a direct parameter from the first form,
// THISform knows about its own Picture property and can directly
// set the visibility within its scoped control.
this.YourPicture.Visible = ShowTheImage
}
Related
I am currently making an rpg using Winforms for a school project. However my knowledge on classes is so limited that I'm having trouble making a proper class that takes in data from 1 form, is used in the second form, then sent back to the first form.
The process I'm trying to accomplish is like this:
main form opens a second form that displays items in a listbox.
1
when you select an item and press a button to use it, the items effects are applied.
2
The data for the effect is in the first form where many other calculations are made with the same data.
3
I keep running into the problem of making a new object of a class and the data from the first form is reset. How would I go about either using an existing object from the first form, or creating a reference class maybe?
This is the function I want to run on the first form when the button on the second form is clicked.
public void SmallPot()
{
currentPHP += pHP * .25;
if (newPHP > pHP)
{
newPHP = pHP;
}
pHPBarUpdate = (int)(newPHP / pHP * 377);
pnlCurrentPHP.Width = pHPBarUpdate;
newPHP = currentPHP;
}
Expected:
When I click the use button on the popup form it closes and the items effects are displayed on the Main form.
What Happens:
Since I create a new object of form one in form two, all my variables are reset to 0 before the calculation, resulting in nothing happening after the second form closes.
I will give you a general guideline to implement a solution based on event definition and raising
Let's start from your second form where you need to communicate to the first form the event
public class Form2 : Form
{
// start creating the delegate type
public delegate void OnItemSelected(string itemName);
// declare the public event that this form will raise
public event OnItemSelected ItemSelected;
protected void cmdItemUse_Click(object sender, EventArgs e)
{
// When the user clicks to select an item....
string itemName = GetItemSelectedFromList();
// Check if someone is interested in this item selection
if(ItemSelected != null)
ItemSelected.Invoke(itemName);
}
}
Now we change something in the first Form. We need to create the second form and before displaying it we subscribe to the event exposed by the second form
public class Form1 : Form
{
... other stuff....
protected void cmdOpenSelection_Click(object sender, EventArgs e)
{
using(Form2 frm = new Form2())
{
// Subscribe the event giving it a method inside this class
// that doesn't return anything and receives a string
// as required by the delegate type of the event
frm.ItemSelected += handleItemSelection;
frm.ShowDialog(); // frm.Show();
}
}
private void handlerItemSelection(string itemName)
{
// This method is a custom Event handler and inside Form1
// will be called by Form2 through the Invoke on the event variable
}
}
In the example above I choose to pass a simple string, but of course you could pass anything including a reference type like an instance of a class containing all the info
required by the Item selection.
I have a button and hidden textbox on my main form. When I press the button it will hide the main form and show the second form. When I press the button on the second form I want to show the main form again but this time I need to show the hidden textbox. I know how to pass the text from a textbox to another form but not just the reference of the textbox.
You better pass the complete main form instance for the second form, and create a public function to set the textbox to visible, or create a property around it.
Something like:
//form1
Form2 second = new Form2(this);
}....
public void ShowTextBox()
{
textbox1.Visible=true;
}
//form2
Form parent;
public Form2(Form _parent)
{
parent=_parent;
}
///later
parent.Show();
parent.ShowTextBox();
Sounds to me like a custom event would be a better approach. Have the secondary form expose an event, which is raised at whatever appropriate time (your button press). In your main form, when you create your instance of your second form, subscribe to that event. Then run your "unhide" code from within the mainform's event subscription.
This keeps the coupling down on the two forms and results in much more easily maintainable and extensible code (for best effect, use interfaces, but events are a good middle ground for learning).
Something like this:
(it's been a long time since I worked with winforms, or events even, so if this needs refining let me know)
// your secondary/popup form's class
public partial class Form2 : Form
{
// add a custom event
public EventHandler<EventArgs> MyCustomEvent;
// link up your button click event
void InitializeComponent() {
myButton.Click += myButtonClick;
}
// when your button is clicked, raise your custom event
void myButtonClick(object sender, EventArgs, e) {
onMyCustomEvent();
}
// this "broadcasts" the event
void onMyCustomEvent() {
EventHandler<EventArgs> h = MyCustomEvent;
if (h != null) {
h(this, new EventArgs());
}
}
}
// your main form's class
public partial class MainForm
{
void InitializeComponent() {
// ...
}
void showForm2() {
var form2 = new Form2();
form2.MyCustomEvent += form2CustomEvent;
form2.Show();
}
void form2CustomEvent(object sender, EventArgs e) {
myHiddenTextBox.Visible = true;
}
}
All in all this is a much better approach in terms of code architecture. Now the popup doesn't care who opens it (it has no reference to the main form), and the custom event (which is really what you're after) can be managed to any level of control you need, without interfering how other thing work (for example, perhaps later you may want to have a different action that fires this same custom event...)
Food for thought.
Is there any way to have a messagebox immediately pop up when a form opens? I just want to display a short message about how to use the form when it opens. I tried
private void myForm_Load(object sender, EventArgs e)
{
DialogResult dialogOpen = MessageBox.Show("Use the navigation menu to get started.", "Welcome!", MessageBoxButtons.OK);
}
but it doesn't work.
Showing a MessageBox during Form_Load works just fine for me. I literally copy/pasted the code from your original post, and it worked. I'm on .NET Framework 4.5 on Windows 8.1.
Are you sure your Load event handler is getting called? Perhaps the it's not hooked up to the Load event properly.
I don't see why it wouldn't work in Form_Load. Definitely try doing as others have pointed out by putting it beneath form initialization.
Though, given that you're just showing a message box, I don't think there is any reason to store the result, so a simple MessageBox.Show(message); Should do the trick.
As #s.m. said, from a UX point of view, having a notification thrown in your face as soon as the app starts would be very obnoxious, at least if you have it EVERY time. Personally, I would create a boolean Settings variable, set it to true the first time the message is displayed, and only display it when the setting is false, i.e. the first time the message is displayed.
private boolean splashShown = Properties.Settings.Default.splashShown;
private void Form_Load(object sender, EventArgs e)
{
if (!splashShown)
{
MessageBox.Show("message");
myForm.Properties.Settings.Default.splashShown = true;
myForm.Properties.Settings.Default.Save();
}
}
And set up the splashShown Setting in your form properties.
If the problem is that your Form_Load() method isn't actually attached to your Form.Load() event, you can double click the form window in the designer and it will automatically created the Form_Load() base method for you and attach it to the Form.Load() event
Is there a reason to use the Load method of the form? If not you could to it in the constructor of form. If you want it to show up immediately after your form loads, you should do it in the constructor after the form is initialized. It should look something like this:
public partial class myForm : Form
{
public myForm()
{
InitializeComponent();
DialogResult dialogOpen = MessageBox.Show("Use the navigation menu to get started.", "Welcome!", MessageBoxButtons.OK);
}
}
The constructor (public myForm()) and the InitializeComponent(); should be automatically added to the form by Visual Studio after creating it.
Form_Load event occurs before the form is really visible.
I use:
static private bool splashShown = false;
private void Form1_Activated(object sender, System.EventArgs e)
{
if (!splashShown)
{
MessageBox.Show("message");
splashShown = true;
}
}
I have used this and it works fine. App start brings up messagebox first before all else.
InitializeComponent();
MessageBox.Show("put your message here");
I am trying to change a tabpage name on a parent form to what a user types in a textbox on a child form when a strip menu button is clicked. I have everything working in that I can pull the correct information between both forms but every time it goes to get the currently selected tabpage it always returns "0".
Function to set new tabpage name on Forum1 (The message boxes are from trying to debug)
public void setNewTabName(string TextBoxText)
{
MessageBox.Show("Called");
MessageBox.Show(TextBoxText);
int CurrentSelectedTab = tabControl1.SelectedIndex;
MessageBox.Show(CurrentSelectedTab.ToString());
tabControl1.TabPages[CurrentSelectedTab].Text = TextBoxText;
}
Function (Form2) for getting the textbox info and passing it to Form1
private void button1_Click(object sender, EventArgs e)
{
BT frm1 = new BT();
frm1.setNewTabName(getTextBoxInfo());
}
public string getTextBoxInfo()
{
return textBox1.Text;
}
Any help would be greatly appreciated. I think I posted all the relevant code but if you need anything else I can post the whole thing. The only thing that is really left out is that it creates a new tabpage on a button click.
Edit: The same method works fine when it is taken out of the child GUI.
I think that the problem is that you create a new form (class BT) each time the button is clicked. I suggest you to move the form creation from button click event to parent form load function.
I have a data grid that displays data from a sql server. I have an add button, that when clicked it opens a new window where the user can put the information for the new item that is being added. When the user clicks save, the data is being saved to the database, but its not showing up the in the grid. Is there a way that I can make the datagrid bind when the add window is closed? Let me know if more info is needed. Thanks.
In my main window, that contains the datagrid code, i have an add button:
private void btnAdd_Click(object sender, RoutedEventArgs e)
{
showAddWindow();
}
And, the showAddWindow method is:
private void showAddWindow()
{
add addWindow = new add(dgDataView);
addWindow.Owner = this;
addWindow.WindowStartupLocation = WindowStartupLocation.CenterOwner;
addWindow.ShowDialog();
}
If you know the Id of new inserted object, then you can send it to the main form, and call Add.Row on the grid with the new info. This way you'll not make a callback to the database for rebinding.
Assuming this is WinForms:
First, when calling the "Add" window, use ShowDialog() instead of Show()
In the main form with the DataGrid the code would look like
private void btnAdd_Click(Object sender, EventArgs e)
{
DialogResult b = frmAdd.ShowDialog();
if(b == DialogResult.Ok)
{
// code to re-bind the grid here.
}
}
in the frmAdd form, you will need to make your Save button set the DialogResult for the form to be DialogResult.Ok after updating the database.
I'm guessing that what you have tried is along the lines of:
private void btnAdd_Click(Object sender, EventArgs e)
{
frmAdd.ShowDialog();
// code to re-bind the grid here.
}
The difference is that with the ShowDialog() call, the main form will wait until the "add" form is closed to continue executing. In my second code sample, just using Show(), the code to re-bind the grid happens immediately after showing the "Add" form, before the user gets a chance to update the data.
(note, I did that code off the top of my head, not in Visual Studio, so it may have mistakes)