Is there a Form.Showdialog equivalent for Gtk# Windows?

好久不见. 提交于 2019-12-07 19:44:49

问题


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 values None, OK and Cancel.

  • 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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!