Update form from form closing event on another form - c#

I am trying to update a datagridview on my 'switchboard' to solve a concurrency issue. The switchboard has many checkboxes to check off when certain processes are done. When I click a checkbox on a record that has been edited I get a concurrency error as the dgv is not up to date.
I tried doing this:
How to refresh datagridview when closing child form?
to no avail as it raises other errors throughout my project.
Any help on how to refresh my datagridview on my switchboard on the form closing of another form would be great.
Thanks
public partial class frmSwitch : Form
{
public frmSwitch()
{
//'add a label and a buttom to form
InitializeComponent();
}
public void PerformRefresh()
{
this.propertyInformationBindingSource.EndEdit();
this.propertyInformationTableAdapter.Fill(this.newCityCollectionDataSet.PropertyInformation);
this.propertyInformationDataGridView.Refresh() }
}
public partial class frmSummary : Form
{
frmSwitch _owner;
public frmSummary(frmSwitch owner)
//public frmSummary()
{
InitializeComponent();
_owner = owner;
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.frmSummary_FormClosing);
}
private void frmSummary_FormClosing(object sender, FormClosingEventArgs e)
{
_owner.PerformRefresh();
}
That is what I attempted to do but it caused issues in other instances when I needed to open Form2. The issue specifically occurs in the original opening of form 2 which is as follows:
private void propertyInformationDataGridView_CellContentDoubleClick(object sender, DataGridViewCellEventArgs e)
{
System.Data.DataRowView SelectedRowView;
newCityCollectionDataSet.PropertyInformationRow SelectedRow;
SelectedRowView = (System.Data.DataRowView)propertyInformationBindingSource.Current;
SelectedRow = (newCityCollectionDataSet.PropertyInformationRow)SelectedRowView.Row;
frmSummary SummaryForm = new frmSummary();
SummaryForm.LoadCaseNumberKey(SelectedRow.CaseNumberKey, true, null);
SummaryForm.Show();
}

It sounds like you are trying to create a new instance of your Switchboard form instead of modifying the existing instance of the form. When you open a form from the switchboard, I would suggest passing in instance reference to the switchboard form. Then, when you close the opened form, in your form_closing event you would refer to the passed in instance as the Switchboard form to update.
This method and others are specified in this article:
http://colinmackay.co.uk/blog/2005/04/22/passing-values-between-forms-in-net/

Related

C# parent-child round trip Close() not working properly but Hide() does

I'm working on a C# console/winforms desktop app. It monitors some local drive properties and displays a status message on a user defined schedule via Task Scheduler. Multiple schedules can be saved by the user. Below are the actions taken to select/activate a particular saved schedule (the screenshots are sized at 50% and consolidated into a single graphic):
Screenshot A: click on “Change Active” button to call child form
Screenshot B: select a schedule from Combobox and click Activate
Selected Schedule which closes the child form, passing the selected
schedule for processing.
Screenshot C – result using Close()method:
The schedule definition screen is populated with the selected
schedule’s details including (if needed) calling a different child
form BUT the select active schedule form in not actually closing
before the parent form starts the processing for populating the data; Child1 only closes after Child2 is closed by clicking Save or Cancel.
Screenshot D – result using Hide()method: working as intended
Relevant code (I think)
public interface IselectSchedule
{
void SelectSchedule(string sName);
}
/// Parent form
public partial class DefineSched : Form, IDates, IDoWs, IselectSchedule
{
/// calling Child1
private void ChangeActvLBLasBTN_Click(Object sender, EventArgs e)
{
SetActvSchedule callSetActvSched = new SetActvSchedule(this);
callSetActvSched.StartPosition = FormStartPosition.Manual;
callSetActvSched.Location = new Point(this.Left + 45, this.Top + 25);
callSetActvSched.ShowDialog();
}
}
/// Child1 form
public partial class SetActvSchedule : Form
{
IselectSchedule _callingForm;
public SetActvSchedule(IselectSchedule caller)
{
InitializeComponent();
_callingForm = caller;
}
/// form content
private void SaveBTN_Click(Object sender, EventArgs e)
{
this.Close(); // not achieving my objective but Hide does
_callingForm.SelectSchedule(_sname);
}
}
/// back in Parent form
public void SelectSchedule(string sName)
{
_sName = sName;
bool useDB = false;
SetActvDisplay(useDB);
EditSaved(useDB);
}
private void EditSaved(bool useDB)
{
/// populate parent form data & call Child2
SelectDoW callSelectDoWs = new SelectDoW(this, det, det2);
callSelectDoWs.StartPosition = FormStartPosition.CenterParent;
callSelectDoWs.ShowDialog(owner: this);
/// ready for editing
I’ve researched/understand the Hide vs Close decision and think Close is appropriate here. My question is since Close() precedes returning to the parent form why isn’t that action completed before the parent form starts processing the passed info?
Thanks in advance for any insights.
Whilst I believe I nearly got the multi-thread approach suggested above to work I ran into a cross-Threading error I couldn’t resolve. Upon further consideration I may have been pursuing an unnecessarily complicated solution to achieve a very simple objective; present the user with some options and act on their selection.
The simple solution utilizes a public static field in the parent form that is set in the child form after which the child is cleanly closed and control returns to the parent form:
/// Parent form
public partial class DefineSched : Form
{
public static string _sName;
/// calling Child
private void ChangeActvBTN_Click(Object sender, EventArgs e)
{
SetActvSchedule callSetActvSched = new SetActvSchedule();
callSetActvSched.ShowDialog();
ActvSchedOptions();
}
}
/// Child1 form
public partial class SetActvSchedule : Form
{
private void SaveBTN_Click(Object sender, EventArgs e)
{
DefineSched._sName = _sname;
this.Close();
}
}
/// back in Parent form
ActvSchedOptions()
{
/// series of conditional statements
This approach circumvents the need for the Interface and avoids overloading the UI thread. I suspect it’ll not be considered a particularly elegant solution but it has one redeeming virtue: it works flawlessly for the task at hand.

How to transport information from one form to another using dto, C# Windows Forms?

I'm having trouble transporting information from one form to another, is to make a single save, but the information is distributed in 2 forms and I have to do it using dto. I know that for this I have to send the data that I want by the form builder method, as you can see in the code below:
public FrmModalFornecedor(int providerId, int providerDoc)
{
InitializeComponent();
CbxListarFornecedor();
providerDoc = Convert.ToInt32(txtDoc.Text);
providerId = Convert.ToInt32(((Provider)cbxFornecedor.SelectedItem).ProviderId);
}
But now my questions are:
How to make these variables take their respective text box and combo box values?
How to make the next form have access to this data?
You can create additional properties in the second form and you can pass the values from first form to second form.
Hope this gives some ideas for you.
private void button1_Click(object sender, EventArgs e)
{
Form2 frm = new Form2();
frm.MyName = "Pass my name here";
frm.Show();
}
public partial class Form2 : Form
{
public string MyName { get; set }
public Form2()
{
InitializeComponent();
}
}

Form 2 textbox displays in form 1 listbox

I currently have two forms, one to display information when a user is selected from the listbox(the listbox lists names, when selected it will fill a few textboxes I have, one for city and another for address), the second form allows me to input the information for the user, which when I click submit will display them in my listbox on form1. Currently I am able to add the user from my second form to my first form into the listbox, but I am having issues filling their information in the textbox whenever I click on their names in my listbox.
As of now I have tried implementing different code snippets, but being a beginner I'm not sure how to do this.
My first form is as follows
public Form1()
{
InitializeComponent();
}
private void ButtonAddUser_Click(object sender, EventArgs e)
{
Form2 form = new Form2(textBoxFirstName.Text, listBoxUsers);
form.Owner = this;
form.ShowDialog();
form.Show();
}
private void listBoxUser_SelectedIndexChanged(object sender, EventArgs e)
{
if (listBoxUser.SelectedIndex != -1)
{
User selected = (User)listBoxUser.SelectedItem;
textBoxStreet.Text = selected.Street;
textBoxCity.Text = selected.City;
}
}
My second form where I add the users information is as follows
public partial class Form2 : Form
{
private ListBox _listBoxUsers;
public Form(string value, ListBox listBoxUser)
{
InitializeComponent();
value=($"{textBoxFirstName.Text} {textBoxLastName.Text}");
_listBoxUsers = listBoxUsers;
}
private void ButtonSubmit_Click(object sender, EventArgs e)
{
_listBoxUsers.Items.Add($"{textBoxFirstName.Text}
{textBoxLastName.Text}");
this.Close();
}
}
And my Class where I am trying to store the textbox information
public class User : EventArgs
{
public string Street {get; set;}
public string City {get;set;}
public User(string street, string city)
{
Street = street;
City = city;
}
}
In Short: I'm trying to save information from my second form into my class, and when I select a user from my listbox it will display his street and city into textboxes (my listbox and textboxes are both on my first form.).
Thanks for any help
In the second form you should be creating User object and fill the details like street and city .
private void ButtonSubmit_Click(object sender, EventArgs e)
{
User user = new User(textBoxFirstName.Text, textBoxLastName.Text);
_listBoxUsers.Items.Add(user);
this.Close();
}
Since Listbox.Items expecting object type, you can add anything which is derived from System.Object. But in the form1 you have created list with User Objects and during selected index changed you are type casting as User Object. But in the form2 you have not actually inserted User object during the submit button click .
Because of this, i think you are facing this problem . Try with above code and check
I would suggest decoupling state management from the presentation. For example, try to create a separate class for User that is not derived from EventArgs. And manage its state inside a separate class - for start int will be in-memory storage. But as you flesh out your implementation you can latter move your data to Database with ease as it will not rely on UI and its elements for storage and management.

How can I make a form's controls not load until at least the frame of the form has been displayed?

I have a C# Winforms form that has a ton of custom controls that take about 10 seconds to load. Right now, when I click the menu item to open my form, the menu freezes for 10 seconds, and then the form just pops up ready to go. What I'd like to do is the following: As soon as you click the appropriate menu item to open up my form, I want to display the form immediately, but perhaps with just a red background and no controls on it. Then the form can start trying to load all my controls. That way the user sees that their mouse click opened the new form, and it doesn't look like the whole app froze. Moving it to a new thread is not an option.
Have you tried putting your user controls in a seperate user control, then instantiate it in your Shown event and then add it to your form.
i.e. something like this
Form1
public partial class Form1 : Form
{
UserControl1 usr;
public Form1()
{
InitializeComponent();
}
private void Form1_Shown(object sender, EventArgs e)
{
usr = new UserControl1();
usr.Dock = DockStyle.Fill;
panel1.Controls.Add(usr);
}
}
UserControl1
public partial class UserControl1 : UserControl
{
public UserControl1()
{
System.Threading.Thread.Sleep(10000);
InitializeComponent();
}
}

How do i show a new form from usercontrol?

I'm making a usercontrol which is a file manager (cut ,copy ,paste .. etc)
so while moving/coping files .. i had to show a messagebox when the file is already exist .. to let the user to confirm overwrite it or cancel .. but i need 4 buttons [YES][YES TO ALL][NO][CANCEL]
so i made a new form called "MyMessageBox" which contains the 4 buttons and a label.
my problem is .. in (userControl1.cs) i can't initialize the form like this:
MyMessageBox msgbox = new MyMessageBox("overwrite file ?");
First of all you need to make sure that your usercontrol has visibility of the form that you created(i.e. if your form is in another namespace or project you will need to use a using statement or add a project reference in order for your usercontrol to be able to use it.) and that your constructor is what you are thinking it is as M.Babcock is suggesting. You can try something like this
UserControl:
public partial class UserControl1 : UserControl
{
MyMessageBox msgbox;
public UserControl1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
msgbox = new MyMessageBox("Overwrite File ?");
msgbox.ShowDialog();
}
}
CustomMessageBox:
public partial class MyMessageBox : Form
{
public MyMessageBox( string Message)
{
InitializeComponent();
label1.Text = Message;
}
}
Which will give you a result like this.

Categories

Resources