I have recently created a Database in Visual Studio. I have two forms, the first form displays a table. The second form is connected to the first table and displays the information in a design view.
When the user changes the data in the design view, if they click save, the changed information is updated on the original form when the second form is closed.
However, if they close the form without saving, the information on the original form remains unchanged.
I want to create a Save button to clearly show the user that they must save any changes they make in the design view.
Has anyone created a 'save' button before? For a form connected to another form, not a file?
What about using the event FormClosing ?
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (MessageBox.Show("Do you want to save changes to your table?", "My Application", MessageBoxButtons.YesNo) == DialogResult.Yes)
{
e.Cancel = true;
}
}
Not sure if I understood your question correctly but I put together this little example to try and replicate what you were asking.
Here is the main form:
The main form consists of a data grid view (showing data that could have come from a database) and an edit button that is used to open a second form that will be used to edit the DataValue of the selected item in the grid view. Form2 (the edit form) looks like this:
As you can see I put a Save button and a Cancel button on Form2. I am using Form2 as a modal dialog form (so the test form cannot be changed while Form2 is open). This means I can set the DialogResult properties of the Save and Cancel buttons and use these to inform the TestForm what to do. The Save button is set so that DialogResult = OK and the Cancel button is set so that DialogResult = Cancel.
I also added a special public property to From2 that can be used to get and set the data. In my case this is just a simple string, but in a more advanced case this would get and set an object of a special type or perhaps a data row from the table. Here is my property:
public string DataValue
{
get { return textBox1.Text; }
set { textBox1.Text = value; }
}
Now behind my Edit button on the TestForm I have the following event code:
private void EditButton_Click(object sender, EventArgs e)
{
if (dataGridView1.SelectedRows.Count != 1) { return; }
string data = dataGridView1.SelectedRows[0].Cells[1].Value.ToString();
// show the form as a modal dialog box while editing.
Form2 editForm = new Form2();
editForm.DataValue = data;
if (editForm.ShowDialog() == DialogResult.OK)
{
// If the user clicks Save then we want to update the datagrid
// (and eventually the database).
dataGridView1.SelectedRows[0].Cells[1].Value = editForm.DataValue;
}
}
If you need a non-modal version of Form2 then you will not be able to do all this within the edit button event. Instead you will have to spawn a new edit form and handle it's close event. You will then need to move the code that updates the grid view into this close event. Each spawned edit form will need to remember which data row it is editing so that the close event can update the correct row.
I hope this helps.
so if you want to save it you can use this code for the save button
// Displays a SaveFileDialog so the user can save the Image
// assigned to Button2.
SaveFileDialog saveFileDialog1 = new SaveFileDialog();
saveFileDialog1.Filter = "html|*.html|lua file|*.lua|text
document|*.txt|video|*.mp4|image|*.jpg";
saveFileDialog1.Title = "save project";
saveFileDialog1.ShowDialog();
// If the file name is not an empty string open it for saving.
if (saveFileDialog1.FileName != "")
{
// Saves the Image via a FileStream created by the OpenFile method.
System.IO.FileStream fs =
(System.IO.FileStream)saveFileDialog1.OpenFile();
// Saves the Image in the appropriate ImageFormat based upon the
// File type selected in the dialog box.
// NOTE that the FilterIndex property is one-based.
switch (saveFileDialog1.FilterIndex)
{
case 1:
this.button2.Image.Save(fs,
//change button number to what your button number is
System.Drawing.Imaging.ImageFormat.Jpeg);
break;
case 2:
this.button2.Image.Save(fs,
System.Drawing.Imaging.ImageFormat.Bmp);
break;
case 3:
this.button2.Image.Save(fs,
System.Drawing.Imaging.ImageFormat.Gif);
break;
}
fs.Close();
Related
Complete C# beginner here, just wondering how to open an existing form from within the current form, and close the first one. I have literally no code yet so any help is much appreciated
I had a bit of a mess around, of course not knowing anything. Something like this is about all I tried just going off of intellisense prompts:
Application.Run(Terry2);
It obviously didn't work. Here was the error
Error CS0119 'Window2' is a type, which is not valid in the given context.
I have no idea where to start so thanks in advance for the help. I am using Visual Studio 2022.
Actually there are plenty of examples for this code on the internet, first you should create both of your forms and then just create an instance of your form2 in form1 under the event of your form1's button and call it's Show() method.
private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
f2.ShowDialog(); // Shows Form2 you can also use f2.Show()
}
Here is a step by step explenation of the process that you should follow. I recommend you to watch some fundamental c# programming tutorials as well.
Click Here
If you've used windows for some time, you've noticed that there are two types of Dialog Boxes (forms): Modal and Modeless Dialog Boxes
Modal dialog boxes: while this one is being shown, you cannot use the other dialog boxes of the application; you'll have to finish this one before you can continue using your application. Example: File Open dialog box.
Modeless Dialog Box. A kind of dialog box that gives some extra information next to the other dialog box of your application. While this one is being shown, you can switch back to your original dialog box and enter some input.
How to show a modal dialog box
For this, you use Form.ShowDialog
In your form:
private DialogResult AskFileName()
{
using (Form myForm = new SaveFileDialog();
{
// Before showing the dialog box, set some properties:
myForm.Title = "Save file";
myForm.FileName = this.DefaultFileName;
myForm.ValidateNames = true;
...
// show the file save dialog, and wait until operator closes the dialog box
DialogResult dlgResult = myForm.ShowDialog(this);
// if here, you know the operator closed the dialog box;
return dlgResult;
}
}
private void SaveFile()
{
DialogResult dlgResult = this.AskFileName();
switch (dglResult)
{
case DialogResult.Ok:
// File is saved:
this.HandleFileSaved();
break;
case DialogResult.Cancel();
// operator pressed cancel
this.ReportFileNotSaved();
break;
...
}
}
A form is disposable, hence you should use the using statement. After creation of the form you have time to set the properties. The form is shown using ShowDialog. While this dialog box is shown, your form can't get the focus. After the operator closes the dialog box, your form gets the focus again. The return value of ShowDialog indicates the result.
If you want to save the file as a result of the operator selecting the menu item "file save", or pressing the button "Save", do the following:
private void OnMenuItemFileSave_Clicked(object sender, ...)
{
this.SaveFile();
}
private void OnButtonSave_Clicked(object sender, ...
{
this.SaveFile();
}
How to show a modeless Dialog Box
A modeless dialog box is shown using Form.Show. After you call this, your dialog box can get the focus. Therefore you'll have to remember that the form is being shown.
class MyModelessDialogBox : Form {...}
class MyForm : Form
{
private MyModelessDialogBox {get; set;} = null;
private void ShowMyModelessDialogBox()
{
if (MyModelessDialogBox != null)
{
// Dialog box already shown, TODO: report to operator?
...
return;
}
else
{
// Dialog box not shown yet; create it and show it
this.MyModelessDialogBox = new MyModelessDialogBox();
// if needed, before showing set some properties
// make sure you get notified if the dialog box is closed
this.MyModelessDialogBox.FormClosed += new FormClosedEventHandler(this.MyModelessDialogBoxClosed);
// show the dialog box:
this.MyModelessDialogBox.Show(this); // I am the owner / parent window
}
// when the modeless dialog box is closed, you get notified:
void MyModelessDialogBoxClosed(object sender, FormClosedEventArgs e)
{
// if needed, inspect e.CloseReason
// if needed, handle the DialogResult
// finally: not my form anymore. The form should disposes itself:
this.MyModelessDialogBox = null;
}
}
}
}
Before closing your form you should check if the dialog box is being shown, and close:
private void OnFormClosing(object sender, FormClosingEventArgs e)
{
if (this.MyModelessDialogBox != null)
{
// the modeless dialog box is being shown. Order it to close itself:
this.MyModelessDialogBox.Close();
// this will lead to MyModelessDialogBoxClosed
}
}
Sometimes you have a dialog box that refuses to close, for instance because the dialog box warns the operator and he clicks cancel. In that case, you should not Close the dialog box directly, but add a method to ask the dialog box nicely.
In the dialog box:
bool RequestToClose()
{
bool allowedToClose = this.AskOperatorIfCloseAllowed();
if (allowedToClose)
{
// close this dialog box.
this.Close();
// the owner of the dialog box will be notified via MyModelessDialogBoxClosed
}
return allowedToClose;
}
I have a button that loads a Form, as it gets lots of data from a database and takes a few seconds, I want to advise the user to wait.
When I click the button the button text does not change.
This is the button Click code I am using:
private void btnItemConfigForm_Click(object sender, EventArgs e)
{
var itemConfigBtnText = btnItemConfigForm.Text;
btnItemConfigForm.Text = "Waiting...";
ItemConfigForm form = new ItemConfigForm();
form.Show();
if (form.Created)
{
btnItemConfigForm.Text = itemConfigBtnText;
}
}
If I Comment out
if (form.Created)
{
btnItemConfigForm.Text = itemConfigBtnText;
}
Then the button text changes to waiting after the new form window is visible.
What am I missing to get the button text to change before the form window is visible.
the simple solution is to add this row:
btnItemConfigForm.Refresh();
after this row
btnItemConfigForm.Text = "Waiting...";
Otherwise the text of the button will be changed only when the function ends, this function will redraw the form display!
P.s.
If you want the form will not be blocked - you can use in asynchronic running to the function "Show" (or New) then you will need Event to notify the first form when the form will be loaded
sorry for my English... :)
Added
btnItemConfigForm.Update();
under
var itemConfigBtnText = btnItemConfigForm.Text;
btnItemConfigForm.Text = "Waiting...";
This updates the button Control before moving on to initialising and showing the form.
I have the following situation: The main window where some of the data is completed, it is also a button that opens a new modal window where you choose the product and the range of products, I click OK and move on to the next screen where choose the quantity, price, and after approval of the data which I click OK, I want to have access to the data selected in modal windows in the main window, as it can be done using C #?
You can do something that looks more or less like this:
private void button1_Click(object sender, EventArgs e)
{
Form2 firstPopup = new Form2();
firstPopup.ShowDialog();
var someData = firstPopup.SomeValue;
Form2 secondPopup = new Form2();
secondPopup.ShowDialog();
var someOtherData = secondPopup.SomeValue;
doSomeStuff(someData, someOtherData);
}
In this case SomeValue is a property on the form with a public getter and a private setter. It's value will be set sometime before the form is closed. You can have any number of such properties per form, and any number of forms.
This is similar to the way that Open, Save As and Folder dialogs work. Take for example the Open File Dialog, once you click OK, you have access to the file that was selected
Suggestion:
In your modal window, set some public properties which hold your data. Set your OK button to set the forms DialogResult to OK, in your parent form you can do the following test (in this instance, DataModel is the data you are trying to access)
if(modalWindow.DialogResult == DialogResult.OK)
{
this.DataModel = modalWindow.DataModel;
}
Here is some information on how to use DialogResult
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.dialogresult.aspx
Typically with a Modal window you follow a similar pattern to that used by the OpenFileDialog, where you do something like this:
public class MyDialog : Form
{
public MyResult Result { get { /* code elided */ } }
}
I.e, in addition to having the modal form's code - you also expose a public Result property of a given type which can provide the data entered on that form's UI (this is better than exposing the controls on the form as it means you are free to change all of that without having to re-code any other forms that depends on it).
You make sure that the Result is guaranteed to be available and valid if the Ok or Yes (whatever the confirmation button is) button is clicked. Then you make sure that you set the DialogResult of the form accordingly (you can assign one to each button as well - e.g. DialogResult.Cancel to a cancel button).
Then when you open your form you do it something like this:
var form1 = new MyDialog();
if(form1.ShowDialog() != DialogResult.OK)
return; //abort the operation, the user cancelled/closed the first modal
MyResult form1Data = form1.Result; //get your actual data from that modal form.
//...and then on with your second modal
So you collect the data from the modal(s) as you go along, aborting if any are cancelled.
Try not using a modal window!
If you call
var dialog = new DialogWindow();
If (dialog.ShowDialog(mainWindow) == DialogResult.OK) {
use the result of the dialog window
}
the dialog window will be modal, which means that you cannot access other windows while it is open.
With the following code, both windows are accessible at the same time. The problem is, however, that the code in the main window is not paused while the dialog runs.
var dialog = new DialogWindow();
dialog.Show(mainWindow);
You cannot use the result of the dialog window here!
Therefore you need a way to communicate the completion of the dialog to the main window. I suggest creating an event in the dialog window for this purpose
public class ProductResultEventArgs : EventArgs
{
public ProductResultEventArgs(List<Product> products)
{
Products = products;
}
public List<Product> Products { get; private set; }
}
In the dialog window
public event EventHandler<ProductResultEventArgs> ProductsChosen;
private void OnProductsChosen(List<Product> products)
{
var eh = ProductsChosen;
if (eh != null) {
eh(this, new ProductResultEventArgs(products));
}
}
private BtnOk_Click(object sender, EventArgs e)
{
OnProductsChosen(somehow get the product list);
}
In the main window you can do something like this
var dialog = new DialogWindow();
dialog.ProcuctsChosen += Dialog_ProductsChosen
dialog.Show(mainWindow);
and create a handler
private Dialog_ProductsChosen(object sender, ProductResultEventArgs e)
{
use e.Products here
}
Note: Passing the main window as parameter to ShowDialog or Show makes the main window owner of the dialog. This means that the dialog window will always stay in front of the main window and cannot disappear behind it. If you minimize the main window, this will minimize the dialog window as well.
In MainWindow.xaml.cs I want to open another window. My code is this:
WordToHtml.Window1 newForm = new WordToHtml.Window1();
newForm.Show();
return newForm.imagePath;
In Window1.xaml I have label, button and textBox. I want the user to click on the button and then I read the content from the textbox. However, when the breakpoint comes to newForm.Show();, the Window1 is shown but its invisible. It doesn't have label/button etc. This is the code of Window1:
string imagePath;
public Window1() {
InitializeComponent();
label1.Content = #"Please enter path";
}
void button1_Click(object sender, RoutedEventArgs e) {
//this is never entered because I can't see the button
}
public string newImagePath(string imagePath) {
return imagePath;
}
The code snippet you are showing is not making somethings clear. I am pointing out my confusion & questions.
1). I am assuming that when user clicks on some button on MainWindow, a new windows should open "Window1" where there is a label, button and textbox. then user enters some path in the textbox and clicks on the button the window1 should close and the imagepath should be available at "MainWindow" form. Please correct me if i am wrong.
2). In this code snippet
WordToHtml.Window1 newForm = new WordToHtml.Window1();
newForm.Show();
return newForm.imagePath;
You will not get anything at "newForm.imagePath" or null or empty string as you are trying to access this before the user enters any value in the textbox.
3). Using "SomeForm.Show()" method will open the new form which is not modal dialog means user can still get focus of "MainWindow" or click the button (that opens the new Window1 from). I suggest to use "newForm.ShowDialog()" window which returns focus to parent windows only when it is closed.
4). You shold use
newForm.Closing event to get the reference of the new form and before it is closed you can find the textbox control
string imagePath = (newForm.FindName("nameOfTextBox") as TextBox).Content.ToString();
and get the imagepath in the MainWindow.
I would like to disable the combo box which was in the first Form on clicking save on the second Form.
I am having 2 forms and my requirement is to append the 2 forms data together this was done
For my requirement i write a small code but it doesn't work for me
My code is as follows
Form1 i write my code as follows
public void loadingDatafrom(bool str)
{
if (true)
{
cmbServiceClassCode.Enabled = false;
}
else
{
cmbServiceClassCode.Enabled = true;
}
}
Form2 after save and hiding the form2 i call the above method
frmBatch frmbatch = new frmBatch(frmmain);
frmbatch.loadingDatafrom(true);
But this is not working any help please.
I'm not sure to understand your question. From your main form FrmBatch, Call the 2nd form FrmEntry in modal mode. After you Save and close FrmEntry form, you have to disabled combox box. In FrmBatch call this :
Form2 FrmEntry = new Form2();
FrmEntry.ShowDialog();
cmbServiceClassCode.Enabled = false;
The first thing to fix is
if (true) -> if (str)