问题
Using Windows Forms or WPF I can open a dialog window by calling ShowDialog. How can I do that using Gtk#?
I tried just making the Window modal, but although it prevents the user from interacting with the calling window it does not wait for the user to close the dialog before running the code after ShowAll().
回答1:
Instead of using a Gtk.Window, use Gtk.Dialog, then call dialog.Run (). This returns an integer value corresponding to the ID of the button the user used to close the dialog.
e.g.
Dialog dialog = null;
ResponseType response = ResponseType.None;
try {
dialog = new Dialog (
"Dialog Title",
parentWindow,
DialogFlags.DestroyWithParent | DialogFlags.Modal,
"Overwrite file", ResponseType.Yes,
"Cancel", ResponseType.No
);
dialog.VBox.Add (new Label ("Dialog contents"));
dialog.ShowAll ();
response = (ResponseType) dialog.Run ();
} finally {
if (dialog != null)
dialog.Destroy ();
}
if (response == ResponseType.Yes)
OverwriteFile ();
Note that Dispose()ing a widget in GTK# doesn't Destroy() it in GTK# -- a historical design accident, preserved for backwards-compatibility. However, if you use a custom dialog subclass you can override Dispose to also Destroy the dialog. If you also add the child widgets and the ShowAll() call in the constructor, you can write nicer code like this:
ResponseType response = ResponseType.None;
using (var dlg = new YesNoDialog ("Title", "Question", "Yes Button", "No Button"))
response = (ResponseType) dialog.Run ();
if (response == ResponseType.Yes)
OverwriteFile ();
Of course, you could take it a step further and write an equivalent of ShowDialog.
回答2:
I'm trying to create a more complex dialog, one that doesn't have windows - it's a search dialog with a completion treeview nested in a scrollview, and is closed with Enter or Escape.
Here's how I've figured you put together the mechanics of a modal dialog manually:
Define a property on your dialog that indicates whether it is completed or not. I'm calling mine
ModalResult
, an enum with valuesNone
,OK
andCancel
.Ensure you have the parent window of the dialog handy (
dialogParent
below)
Sample code:
// assuming Dispose properly written per @mhutch
using (window = new MyDialogWindow())
{
window.TransientFor = dialogParent;
window.Modal = true;
window.Show();
while (window.ModalResult == ModalResult.None)
Application.RunIteration(true);
// now switch on value of modal result
}
Note however this Ubuntu bug with overlay scrollbars. I don't use them and my app is for personal use, but YMMV.
回答3:
I implemented the following method on my Gtk.Dialog:
public ResponseType ShowDialog()
{
List<ResponseType> responseTypes = new List<ResponseType>
{
// list all the ResponseTypes that you have buttons for
// or that you call this.Respond(...) with
ResponseType.Ok,
ResponseType.Cancel
};
this.Modal = true;
// start with any ResponseType that isn't contained in responseTypes
ResponseType response = ResponseType.None;
while (!responseTypes.Contains(response))
{
response = (ResponseType)this.Run();
}
this.Destroy();
return response;
}
来源:https://stackoverflow.com/questions/990640/is-there-a-form-showdialog-equivalent-for-gtk-windows