Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Programmatically closing a dialog #2633

Open
UCIS opened this issue Mar 10, 2024 · 0 comments
Open

Programmatically closing a dialog #2633

UCIS opened this issue Mar 10, 2024 · 0 comments

Comments

@UCIS
Copy link

UCIS commented Mar 10, 2024

I used a Dialog as a progress/busy indicator for some long-running operations in an application. The Dialog is displayed using ShowModalAsync, locking the parent Form/Dialog, while allowing the application code to start the long running operation and eventually Close the dialog and wait for the ShowModalAsync task to complete and Dispose the form. This seems to work fine sometimes, but breaks down when the operation completes synchronously.

I have tried to wait for the OnShown event to be raised before calling the Close/Dispose methods, and while this seems to work for Wpf it does not seem like a reliable solution, causing different effects on Gtk and possibly not working at all on Mac (#2254).

Is the use of a Dialog as a programmatically controlled progress/busy indicator acceptable? Would there be a better approach to achieve the desired behavior?

Expected Behavior

The dialog opens, blocking the main UI, and closes immediately after, or does not show at all.

  • A Dialog that is asynchronously initialized after Close or Dispose has been called, should just abort the initialization or immediately close after initialization

Actual Behavior

  • On Wpf: I have seen a NullReferenceException and an InvalidOperationException stating that the window was already closed. This error happens on the next UI iteration (RunIteration/MessageBox/main UI loop).
  • On Gtk: If Dispose is used, a NullReferenceException occurs on the next UI iteration. If Close is used, the Dialog Shown event is raised before the dialog is actually visible. A subsequent MessageBox appears first, and then the Dialog appears, raising another Shown event. The dialog does not close.
  • On XamMac/Mac64: Using Dispose results in a NullReferenceException on the UI thread; using Close leaves the Dialog open and manually closing the Dialog results in the main window still being blocked, using Close via AsyncInvoke has no effect.

Steps to Reproduce the Problem

  1. Run the test code below and click the button in the form that appears.
  2. Enabling the form.Close call and running on the Wpf platform produce slightly different results.
  3. (Scheduling the form.Close call on the UI thread seems to work for now)
using Eto.Forms;
using System;

namespace Test {
	class Program {
		[STAThread]
		public static void Main(string[] args) {
			new Application(Eto.Platforms.Gtk).Run(new TestForm()); return;
		}
		class TestForm : Form {
			public TestForm() {
				Content = new Button() { Command = new Command(ButtonClick) };
			}
			async void ButtonClick(object state, EventArgs e) {
				var form = new Dialog();
				_ = form.ShowModalAsync(this);
				//Application.Instance.AsyncInvoke(form.Close);
				//form.Close();
				form.Dispose();
				MessageBox.Show(this, "hi");
			}
		}
	}
}

Specifications

  • Version: 2.8.2
  • Platform(s): WPF, Gtk, XamMac2, Mac64
  • Operating System(s): Windows 10, Mac OS 13.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant