Database only updates after closing and opening dialog - c#

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().

Related

Stopping Button Click Function in C# Winfoms

I have a Save Button that grabs information and stores it in SQL from a Winform.
The issue I'm having is that if you click the save button, it still stores blank information in the database. I don't want this. Here's my code. Keep in mind, the actual saving, updating, getting data work perfectly.
private void btnSave_Click(object sender, EventArgs e)
{
if (txtLocalSourcePath.Text != null)
{
if (ResourceKey == 0)
{
ConnString = ConfigurationManager.ConnectionStrings["Dev"].ConnectionString;
GetData(ConnString);
InsertData(ConnString);
GetData(ConnString);
lblInsertNewRecord.Visible = true;
lblInsertNewRecord.Text = String.Format("You have inserted a new record at {0}", System.DateTime.Now);
}
else
{
UpdateData();
GetData(ConnString);
lblInsertNewRecord.Visible = true;
lblInsertNewRecord.Text = String.Format("Updated Record at {0}", System.DateTime.Now );
}
ClearData();
}
else
{
lblInsertNewRecord.Visible = true;
lblInsertNewRecord.Text = "Cannot add record. Please select file.";
}
}
I have tried these options:
stopping a function executed on a winform button click
How to cancel any event in winforms?
How to cancel winform button click event?
You probably want to try if (txtLocalSourcePath.Text != null && txtLocalSourcePath.Text.Length > 0), or the solution proposed by basher:
if (!string.IsNullOrEmpty(txtLocalSourcePath.Text))
The .Text property is NOT actually null, but instead just a blank ("") string.
Edit: Russ Wilson's recommendation in comments is also handy: if (!string.IsNullOrWhiteSpace(txtLocalSourcePath.Text)), which guarantees that the string is not just spaces/tabs/etc.

Disable a button and an event if a form is open

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;
}

refresh form after button click

I'm getting the first element of a table articles where column(statusArticle=false).The problem is that i want to refresh the form after the button click so i can interact with next element, but the form is not refreshed, i tried several codes exept the one of application.restart that is heavy! How can i refresh the form at the boutton click without restarting application?
private void button_Click(object sender, EventArgs e)
{
using (DbEntities db = new DbEntities())
{
Articles firstArticle = db.Articles.FirstOrDefault(u => u.statusArticle == false);
if (firstArticle != null)
{
firstArticle.statusArticle = true;
db.SaveChanges();
MessageBox.Show("Article validated", "OK");
this.Refresh();
}
}
}
Within your class create the following:
private void ShowArticle(Article article)
{
/* The code currently in your constructor for displaying the
first article goes here */
}
For your constructor:
public MyForm()
{
using(DbEntities db = new DbEntities())
{
Articles firstArticle = db.Articles.FirstOrDefault(u => u.statusArticle == false);
if( firstArticle != null ) ShowArticle( firstArticle );
}
}
In your button click handler instead of calling Refresh simple replace it with a call to ShowArticle passing in "firstArticle". The code above could be cleaned up a bit, but it should do.

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.

Categories