Background Information
My main Form instance is called 'MainView' and contains the following:
- A panel called
contentPanel
that contains various input controls (includingchildControl
, which starts off disabled). - A BackgroundWorker control.
backgroundWorker_DoWork(3-arg)
is called when the Submit button is clicked. contentPanel
is disabled so the user can't make changes, spam buttons, etc while their submission is being processed. If the submission is successful certain UI changes need to also occur (more on this below in the Problem section).
contentPanel relevant code
private void btnSubmit_Click(object sender, EventArgs e)
{
...
Type[] parameterTypes = new Type[] { suiteRel.GetType() };
MethodInfo method = this.GetType().GetMethod("btnSubmit_Click", parameterTypes);
mainView.backgroundWorker_DoWork(this, method, myData);
}
/// <summary>
/// Commits changes to the database.
///
/// Note: This method will be executed from a non-UI thread. As such
/// accessing or modifying UI controls must be done via an Invoke() call.
/// </summary>
public void btnSubmit_Click(Object myData)
{
...
if (success)
{
this.Invoke(new Action(
() => {
childControl.Enabled = true;
}
));
}
}
BackgroundWorker relevant code
/// <summary>
/// Starts another thread to perform a potentially long-running task (e.g. validation, database commits, etc).
/// </summary>
/// <param name="reference">
/// A reference to the control instance that owns the method to be called.
/// </param>
/// <param name="method">
/// The method to be called that will perform the work.
/// </param>
/// <param name="parameters">
/// Parameters to pass to the method when it is called.
/// </param>
public void backgroundWorker_DoWork(object reference, MethodInfo method, params object[] parameters)
{
List<object> methodAndArgs = new List<object>();
methodAndArgs.Add(reference);
methodAndArgs.Add(method);
methodAndArgs.Add(parameters);
contentPanel.Enabled = false;
this.UseWaitCursor = true;
backgroundWorker.RunWorkerAsync(methodAndArgs);
}
/// <summary>
/// Starting point of a worker thread (i.e. not on the UI thread).
/// </summary>
/// <param name="sender">
/// The object that initiated the work request.
/// </param>
/// <param name="e">
/// The arguments that dictate what work to do. In particular, e.Argument
/// contains the parameters passed to the public backgroundWorker_DoWork().
/// </param>
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
List<object> methodAndArgs = (List<object>)e.Argument;
object reference = methodAndArgs[0];
MethodInfo method = (MethodInfo)methodAndArgs[1];
object[] parameters = (object[])methodAndArgs[2];
// call method with its parameters.
// a.k.a. "method(param1, param2, ...);"
method.Invoke(reference, parameters);
}
/// <summary>
/// Called on the UI thread after backgroundWorker_DoWork() completes.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
contentPanel.Enabled = true;
this.UseWaitCursor = false;
}
Problem
When 'method' is executed in backgroundWorker_DoWork(2-arg)
, I set the Enabled property for a child control within contentPanel
to true
. The intention is that the child control will be enabled when contentPanel
is enabled when backgroundWorker_RunWorkerCompleted()
is called. However, the child control remains disabled after backgroundWorker_RunWorkerCompleted()
is called.
I understand that it is not possible to have a child control that is enabled while its parent is disabled (e.g. what this question is asking for), and this is not what I'm trying to do. I want the child control to be enabled when its parent (contentPanel
) is enabled (similar to how other child controls that were enabled before the Submit button was clicked are re-enabled when contentPanel
is enabled in backgroundWorker_RunWorkerCompleted()
).