This is entirely by design, a dialog disables all windows in an application. There's a good reason for that, outlined in this answer.
In brief, the Drastic Failure scenario is that a user could use a command in form A that creates another instance of form B, one that isn't disabled. Which allows you to display C again, now you have two dialogs showing.
You may well sputter that this can never happen in your case. That's okay but you'll then have to undo what ShowDialog() does. Which requires gymnastics, you have to pinvoke EnableWindow() to re-enable the form A instance. But you have to do so after the ShowDialog() call but before it ends. Something you can do by using Control.BeginInvoke() on the UI thread. The trickorama looks like this:
private void ShowDialogButton_Click(object sender, EventArgs e) {
using (var dlg = new Form3()) {
// Find the main form instance
var main = Application.OpenForms.OfType<Form1>().Single();
this.BeginInvoke(new Action(() => {
EnableWindow(main.Handle, true);
}));
if (dlg.ShowDialog(this) == DialogResult.OK) {
// etc..
}
}
}
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern bool EnableWindow(IntPtr handle, bool enable);
You can also put the EnableWindow() call in the dialog's Shown event handler, that avoids having to use the BeginInvoke trick. But this way is more universal, dialogs should in general not be in the business of knowing what other windows run in an app. The use of Form1 in this code is ugly enough as-is.