Disable a button and an event if a form is open - c#

I have two forms. The first form get info from the second form doing it this way:
//First Form
if (e.KeyCode == Keys.F4)
{
FormConsultaAdvogado fca = new FormConsultaAdvogado();
fca.MdiParent = this.MdiParent;
fca.Show();
}
Then, in the second form, I choose what I need to get back to the first form with this:
else if (FormClienteAberto())
{
if (e.KeyData == Keys.Enter)
{
FormCliente fdil = (FormCliente)Application.OpenForms["FormCliente"];
fdil.textBox1.Text = dataGridView1.CurrentRow.Cells[0].FormattedValue.ToString();
fdil.textBox2.Text = dataGridView1.CurrentRow.Cells[1].FormattedValue.ToString();
this.Close();
}
}
In the seconde form, I also have a funcion that verifies if the first form is open:
public bool FormClienteAberto()
{
try
{
Form fc = Application.OpenForms["FormCliente"];
return fc != null;
}
catch (Exception)
{
return false;
}
}
So, my problems are:
1st- I have a button in the 2nd form that, when the first form is open, must be hide
2nd- I have a RowHeaderMouseDoubleClick event that i need to disable too, if the first form is already open, too.
Wish that you guys can help me!!
Regards

If you just need to determine those two things when the second form is opened, something like the following in the second form's Load event should work:
if(FormClienteAberto())
{
thatButton.Visible = false;
thatDataGridView.RowHeaderMouseClick -= thatRowHeaderMouseClickEventHandler;
}

Related

Database only updates after closing and opening dialog

I have a DataGridView inside a form that displays data from a database every time I load the page like this:
private void LoadList(string Input)
{
fieldsDataGridView.DataSource = null;
List<Field> fields = new List<Field>();
fields = fieldsData.GetAllByTaskId(Input);
List<FieldsDGViewModel> fdgvm = new List<FieldsDGViewModel>();
foreach (var item in fields)
{
var f = new FieldsDGViewModel
{
Id = item.Id,
Name = item.Name,
Order = item.Order,
IsPrint = item.IsPrint
};
fdgvm.Add(f);
}
fdgvm = fdgvm.OrderBy(x => x.Order).ToList();
fieldsDataGridView.DataSource = fdgvm;
fieldsDataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
fieldsDataGridView.Columns["Id"].Visible = false;
fieldsDataGridView.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
}
When I double click on an entry in my list, it opens a dialog box containing a form and loads the respective details from that entry. When I save the details, the dialog box closes and in the class where my DataGridView sits, there is this FormClose function that refreshes the DataGridView.
private void FormClosed(object sender, FormClosedEventArgs e)
{
RefreshDataGrid();
RecursiveClearInputs(this.Controls);
fieldIdInput.Text = "";
}
private void RefreshDataGrid()
{
var selected = programInput.SelectedValue;
if (selected != null)
{
var result = programsData.Get(selected.ToString());
if (result != null)
{
programIdInput.Text = result.Id;
LoadList(result.Id);
}
}
if (selected == "-1")
{
RecursiveClearInputs(this.Controls);
programIdInput.Text = "";
fieldIdInput.Text = "";
fieldsDataGridView.DataSource = null;
}
fieldsDataGridView.ClearSelection();
}
However, I am having this issue where the only way that my DataGridView refreshes properly is if I close the main form I am on and reopen it again.
I debugged and managed to capture some results.
Image1: Directly after the Update form is closed. In the fields list, only one entry can have IsPrint = true. However the image shows that both are true.
Image2: After I close and reopen the page containing the DataGridView, it shows this correct result. Only 1 IsPrint = true.
I have tried many methods to solve this issue but I'm not sure why its not refreshing properly.
This is how I open a dialog
EditFields editFields = new EditFields(programIdInput.Text, fieldIdInput.Text, false);
editFields.FormClosed += new FormClosedEventHandler(FormClosed);
editFields.ShowDialog();
EDIT:
I added a dialogresult check but it still doesn't update the datagridview properly. Maybe its a thread issue?
dr = editFields.ShowDialog();
if (dr == DialogResult.OK)
{
RefreshDataGrid();
RecursiveClearInputs(this.Controls);
fieldIdInput.Text = "";
}
I'm just assuming how the OnCklick event looks where you open your Dialog, but I think the problem is that you try to refresh the Datagrid form another Form / Thread. (which will not work)
I suggest you open the dialog form by using ShowDialog and refresh the grid after the Form was closed in the onclick event itself. Try replacing
RefreshDataGrid();
in your FormClosed event with
DialogResult = DialogResult.OK;
Then you are able to handle the grid reloading in your onclick event like this:
EditFields editFields = new EditFields(programIdInput.Text, fieldIdInput.Text, false);
if (editFields.ShowDialog(this) == DialogResult.OK)
{
RefreshDataGrid();
}
else
{
//it was canceled
}
editFields.Dispose();
You need to pass the main form to the detail form.
In the detail form, implement the OnClosing or OnClosed event and call MainForm.LoadList().

I cant hide forms after i have proceeded with my login form

private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
Wrong_Username_or_Password Wrong_Username_Or_Password = new Wrong_Username_or_Password();
Missing_Password_and_Username Missing_Password_And_Username = new Missing_Password_and_Username();
Main Main = new Main();
if (e.KeyValue == 13)
{
e.Handled = true;
e.SuppressKeyPress = true;
if (textBox1.Text == "Test" && textBox2.Text == "Test")
{
Missing_Password_And_Username.Hide();
Wrong_Username_Or_Password.Hide();
this.Hide();
Main.Show();
}
else if (textBox1.Text == "" && textBox2.Text == "")
{
Missing_Password_And_Username.Show();
}
else
{
Wrong_Username_Or_Password.Show();
}
}
}
I can't hide the Missing_Password_And_Username form and the Wrong_Username_Or_Password form after i have proceeded with the login but i can hide this form and i don't know how to hide these two forms and i dont want to use showdialog to make the user close the form because i dont like the "ding" sound when you press outside the form.
As far as I can see, the Problem is that you create on every keypress new instances of the forms Wrong_Username_or_Password and Missing_Password_and_Username. If you have shown one of those form instances during the last keypress event, you will have lost track of them during the current keypress event (since they have just been created and overwritten the respective local form variables). You are actually trying to hide forms you have never shown.
Move the form variables and their initializations out of the keypress event handler and make them local to the this-Form. This should solve it.

How to prevent user interaction with invisible forms?

In my application there appeared a following problem: certain dialogue forms can be interacted with before they are drawn.
The code goes like:
void FunctionCalledFromButtonPressHandler()
{
var f = new MyDialog();
if (f.ShowDialog() == DialogResult.OK)
{
//do things
}
}
The buttons on the starting form and dialog form (one that loses it) are over each other on the touchscreen. If the plac is clicked over twice, there is a pause corresponding to the load of dialog form, and then, without it being shown, wotk in starting form is continued/
How should i go about preventing such sort of behaviour (that is, apart from removing the delay on the loading of dialog)?
Set 'Button.Enabled = false;' on your starting form inside the launching method.
void FunctionCalledFromButtonPressHandler()
{
YOURBUTTON.Enabled = false;
var f = new MyDialog();
if (f.ShowDialog() == DialogResult.OK)
{
//do things
}
YOURBUTTON.Enabled = true;
}
Then in your dialog form set the other Button.Enabled = false; in the form constructor. Then you can set the button to enabled in the Shown event like this:
void MyDialog_Shown(object sender, EventArgs e)
{
OTHERBUTTON.Enabled = true;
}

c# : Create a connect button

I have a login form and a button which check if the user name and the password are true.
but the problem is the code I tried .. I must click on the connect button twice.
but the code should work when I click on the button just once ! Right ?
I think the problem is: the showDialog won't be disappeared if only I click in some button that it's DialogResult set in some value, so in the first click the connexionButton.DialogResult gets the DialogResult.OK value and in the second click the button executes the code.
*you can notice that the event simpleButton1_Click is the event for the connexionButton Button*
this is the event I used :
this.connexionButton.Click += new System.EventHandler(this.simpleButton1_Click);
this is the code I tried :
private void simpleButton1_Click(object sender, EventArgs e)
{
Boolean allowCnx = false;
foreach (var row in myClass.ds.Tables["Users"].AsEnumerable())
{
if (row[1].ToString().ToLower() == idBox.Text.ToLower() && row[2].ToString().ToLower() == mdpBox.Text.ToLower())
{
allowCnx = true;
}
}
if (allowCnx)
{
connexionButton.DialogResult = DialogResult.OK;
}
else
XtraMessageBox.Show("Invalide Information", "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
and this is the code I used to call this login form :
using (login loginForm = new login())
{
var result = loginForm.ShowDialog();
if (result == DialogResult.OK)
this.Show();
else
this.Close();
}
// Points to a different method than the one you posted
// (simpleButton1_Click_1 instead of simpleButton1_Click)
this.simpleButton1.Click += new System.EventHandler(this.simpleButton1_Click_1);
// This isn't simpleButton1_Click_1
private void simpleButton1_Click(object sender, EventArgs e)
Not sure if that is your issue, but it looks like your event handler is a different method than the one you posted. Do you have another method called simpleButton1_Click_1 somewhere in your code and you've just gotten slightly confused?
EDIT: In response to your changes/additions
You seem to have some confusion over ShowDialog and DialogResult.
// When you launch the login form, I do not know what you intended to do with your
// calls to Show() and Close() but so long as you don't instend for them to do
// anything to the loginForm, that's fine.
using (login loginForm = new login())
{
if (loginForm.ShowDialog() == DialogResult.OK)
// Do stuff if logged in
else
// Do stuff if failed
}
private void simpleButton1_Click(object sender, EventArgs e)
{
Boolean allowCnx = false;
foreach (var row in myClass.ds.Tables["Users"].AsEnumerable())
if (row[1].ToString().ToLower() == idBox.Text.ToLower() && row[2].ToString().ToLower() == mdpBox.Text.ToLower())
{
allowCnx = true;
}
if (allowCnx)
{
this.DialogResult = DialogResult.OK; // Don't set the DialogResult of a button. Set it for the form.
}
else
{
this.DialogResult = DialogResult.Abort; // Because we didn't succeed
XtraMessageBox.Show("Invalide Information",
"Erreur",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
You are using simpleButton1_Click_1 instead of simpleButton1_Click.
Infact the code should be:
this.simpleButton1.Click += new System.EventHandler(this.simpleButton1_Click);
EDIT :
yes I just forgot when I copied the event.. I mean
this.connexionButton.Click += new
System.EventHandler(this.simpleButton1_Click);
I think, in this case, you should use a bool instead of a DialogResult, so try:
public bool AllowConnection = false;
private void simpleButton1_Click(object sender, EventArgs e)
{
foreach (var row in myClass.ds.Tables["Users"].AsEnumerable())
{
if (row[1].ToString().ToLower() == idBox.Text.ToLower() && row[2].ToString().ToLower() == mdpBox.Text.ToLower())
AllowConnection = true;
}
if (!AllowConnection)
XtraMessageBox.Show("Invalide Information", "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
And:
using (login loginForm = new login())
{
loginForm.ShowDialog();
if (loginForm.AllowConnection)
this.Show();
else
this.Close();
}
Change your iterator for your rows from AsEnumerable to Rows.
FROM:
foreach (var row in myClass.ds.Tables["Users"].AsEnumerable())
TO:
foreach (var row in myClass.ds.Tables["Users"].Rows)
This may sound odd, but if there is any change to that table, anywhere, while you are iterating through your enumerable it will break your iteration. See DataTableExtensions.AsEnumerable This could be perhaps another process accessing this table at the same time, or using a datareader that has not completed filling the table in before the iteration starts.
Also, try to change your code to access the form's dialog result directly, instead of through the button.
FROM:
connexionButton.DialogResult = DialogResult.OK;
TO:
this.DialogResult = DialogResult.OK;
Your code should only set that if your boolean value is set to true, so you will not be closing the form if your checks are correct.
You need to set the Form.DialogResult to DialogResult.OK, not the DialogResult of the Button.
Some Code:
this.DialogResult = DialogResult.OK
Some Additional Thoughts:
It's clearly better to build a standalone method to check for
existence of the user. Don't do this in the ClickEvent. Maybe you need this method again and then you will rewrite this. This will only produce bloated code.
Prevent Users from clicking the Button before Textboxes are filled with values.

Form closing save changes before close

I have a Windows forms application in C# and I have a form that when the user closes it I ask, "do you want to save the changes"? How can I get the changes in my form? Here is some code:
public partial class DepartEdit : Form
{
string _nameDep; //This variavel get value textbox when form load
{
InitializeComponent();
}
private void DepartamentEdit_FormClosing(object sender, FormClosingEventArgs e)
{
if (txtNameDepart.Text != _nameDep && codDepartament > 0)//Here i compare
{
DialogResult dlg = MessageBox.Show("Save changes?", "Question", MessageBoxButtons.YesNo);
if (dlg == DialogResult.Yes)
{
saveDepart(); // Metod save depart
e.Cancel = false;
}
if(dlg ==DialogResult.No)
{
e.Cancel = false;
}
}
}
There are a lot of textboxs and combo boxes? Is there any other way to get the changes in the form?
A lot will depending on where the information is held.
It you are using DataBinding you should be just monitoring the listChanged event or calling dataTable.GetChanges() if you are using a DataTable.
If the information comes from a class the implements ICloneable and IComparable, then you can take just take a backup copy when intialising the form (and after saving) and when closing you prepare you class for saving and compare it with the original.
Otherwise you can do something like
Declare a private variable
private bool requiresSaving =false;
Declare an event
private void SomethingChanged(object sender, EventArgs e)
{
requiresSaving = true;
}
Hook up this event to the various changed events, eg
this.txtNameDepart.TextChanged += new System.EventHandler(this.SomethingChanged);
(The actual event is sometimes called something different , eg ValueChanged, SelectedIndexChanged , but they can all point to SomethingChanged unless you need a particular event to do something else.)
Check this variable when you are closing the form
private void DepartamentEdit_FormClosing(object sender, FormClosingEventArgs e)
{
if (requiresSaving)
{
....
You also need to set requiresSaving false in the saveDepart method.
Alternatively I have seem code where, when the control is being intialised, the tag value is also set, and the formclosing event loops through each control and compares the original values (in the tag object) with the current values.
Create a string (or string[] I guess) within the Form_Load event and initialise them with the values present when the form first opens.
eg
string oName = nameTextBox.Text;
string oCompany = companyComboBox.Text;
Then during the Form_Closing() event you can check these against the current values
private void Contact_FormClosing(object sender, FormClosingEventArgs e)
{
if (oName!=nameTextBox.Text||oCompany!=companyComboBox.Text)
{
DialogResult result = MessageBox.Show("Would you like to save your changes",
"Save?",
MessageBoxButtons.YesNoCancel,
MessageBoxIcon.Stop);
if (result == DialogResult.Yes)
{
SaveFormValues();
}
else if (result == DialogResult.Cancel)
{
// Stop the closing and return to the form
e.Cancel = true;
}
else
{
this.Close();
}
}
}
Loop the forms controls, and add your event watchers. These events will call a function in the form that will keep a Hashtable or some other various collection up to date w/ the status of any changes to a particular control.
like I have, Hashtable changes;
then each time my event is called, i say, Add Control.Name, and then a change status, whatever you want. Then you have a list of controls that have been updated.
I can go into more detail if need be, hopefully this will get you started.
Well I think the theory is good. There are some problems with the implementation.
if (dlg == DialogResult.Yes)
{
saveDepart(); // Metod save depart
e.Cancel = false;
}
if(dlg ==DialogResult.No)
{
e.Cancel = false;
}
I think it would be a lot similier to write this:
if(dlg == DialogResult.Yes)
{
saveDepart();
}
// You don't need to change e.Cancel to false here unless you set it to true previously.
It's simple
Declare a global variable count=0
Now on your form u might already have a Save button so just increment count on save button click event
Now on form close event just check for the value of count if it's 0 ask user to save info either by reminding by message box
If it's 1 or greater than1 just close the form
I hope u get it

Categories