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

Time:10-30

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 enter image description here

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.

CodePudding user response:

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.

  • Related