2009-10-27 33 views
7

我想顯示我的消息框在其父窗體的中心。如果我移動窗體並顯示消息框,它總是顯示在桌面的中心。我希望它與表單一起出現。 你能給我一些技巧和建議嗎?MessageBox.Show()

回答

3

最好的方法是使用Window Hooks並自己居中消息框。有一篇完美的文章顯示了這種用法。

你可以在這裏找到: http://www.codeproject.com/KB/dialog/CenterDialog.aspx

您還可以使用類在你的應用程序,而潛水太深,瞭解它是如何工作。

+0

文章很棒。在將其應用到我的應用程序之前,只需要瞭解它。 TNX。有更簡單的方法嗎?呃.. – 2009-10-27 08:55:00

+1

最簡單的方法是自己製作一個新的MessageBox表單。這將根據你的口味,並會看起來像你想要的樣子。另外,你可以添加你喜歡的任何功能。 – Yogesh 2009-10-27 09:40:09

2

將消息框窗口的所有者設置爲窗口(使用.Show()的第一個參數),而不是設置所有者。

請參閱here以供參考。

+1

你可以給我一些例子? 我試過這個: IWin32Window win = this; MessageBox.Show(win,「TESTING」); 雖然,相同的結果。 Messagebox仍然彈出在桌面中間 – 2009-10-27 07:36:41

+0

我想這取決於這是什麼。恐怕我的經驗僅限於原生的Win32'MessageBox()'函數,這有點不同,在我意識到你使用的是WinForms之前,我已經完成了一半的回答。所以我修改了我的答案以適應我在參考文獻中找到的內容,但我可能仍缺少一些細節。 :) – 2009-10-27 07:44:46

+1

將消息框傳遞給MessageBox不會在父級的中心顯示消息框。這只是爲了使父母最小化/最大化,並且消息框窗口沒有特定的任務圖標。 – Yogesh 2009-10-27 08:24:30

1

我已經在C#中完成了此操作。這是我記得的。

定義一個類:

public class IWindowWrapper : System.Windows.Forms.IWin32Window 
{ 
    public IWindowWrapper(IntPtr handle) 
    { 
     this.Handle= handle; 
    } 

    public IntPtr Handle 
    { 
     get; 
     set; 
    } 
} 

定義基於MessageBox中的一類。 創建基於MessageBox的一類,並創建一個新的顯示方法:

public string Show(IWin32Window owner) 
{ 
    if(owner == null) 
    { 
    this.ShowDialog(); 
    } 
    else 
    { 
     //parentWindow. 
     this.StartPosition = FormStartPosition.CenterParent; 
     this.ShowDialog(owner); 
    } 

} 

在調用代碼(這裏假設爲一個WinForm和MSGBOX是基於新的消息框類)調用新的顯示方法並在Show上傳遞一個IWindowWrapper實例

msgBox.Show(new IWindowWrapper(this.Handle)) 
+0

當你說「基礎」時,你的意思是繼承嗎?林有點新的C#。 :) – 2009-10-27 08:08:42

+0

是例如公共類MyMessageBox:MessageBox ...等 – ChrisBD 2009-10-27 08:26:44

+0

你不必使用C#來做到這一點,但這就是我使用的。這是你編程的語言嗎? – ChrisBD 2009-10-27 08:27:51

0

這裏是一個非常容易使用的解決方案,它完美的作品:

步驟:

  1. 複製和類粘貼到您的項目。我沒有任何編輯就使用它。
  2. 使用修改過的消息框,使用此行代碼在您的項目:

(內UserControlForm

MessageBoxEx.Show(this, "Please fix the validation errors before saving.", "Validation Errors"); 
1

我做基於對一類這個類Windows窗體,我發現somwehere其他。

只需將該類添加到您的WPF項目,並提供「本」作爲參數傳遞給輔助方法是這樣的:

MessageBoxHelper.PrepToCenterMessageBoxOnForm(this)" 

然後顯示在消息框中:

MessageBox.Show("Hello there!"); 


/// <summary> 
/// This class makes it possible to center a MessageBox over the parent dialog. 
/// Usage example: 
///   MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); 
///   MessageBox.Show("Hello there!); 
/// </summary> 
public static class MessageBoxHelper 
{ 
    public static void PrepToCenterMessageBoxOnForm(Window window) 
    { 
     MessageBoxCenterHelper helper = new MessageBoxCenterHelper(); 
     helper.Prep(window); 
    } 

    private class MessageBoxCenterHelper 
    { 
     private int messageHook; 
     private IntPtr parentFormHandle; 

     public void Prep(Window window) 
     { 
      NativeMethods.CenterMessageCallBackDelegate callBackDelegate = new NativeMethods.CenterMessageCallBackDelegate(CenterMessageCallBack); 
      GCHandle.Alloc(callBackDelegate); 
      parentFormHandle = new WindowInteropHelper(window).Handle; 
      messageHook = NativeMethods.SetWindowsHookEx(5, callBackDelegate, new IntPtr(NativeMethods.GetWindowLong(parentFormHandle, -6)), NativeMethods.GetCurrentThreadId()).ToInt32(); 
     } 

     private int CenterMessageCallBack(int message, int wParam, int lParam) 
     { 
      NativeMethods.RECT formRect; 
      NativeMethods.RECT messageBoxRect; 
      int xPos; 
      int yPos; 

      if (message == 5) 
      { 
       NativeMethods.GetWindowRect(parentFormHandle, out formRect); 
       NativeMethods.GetWindowRect(new IntPtr(wParam), out messageBoxRect); 

       xPos = (int)((formRect.Left + (formRect.Right - formRect.Left)/2) - ((messageBoxRect.Right - messageBoxRect.Left)/2)); 
       yPos = (int)((formRect.Top + (formRect.Bottom - formRect.Top)/2) - ((messageBoxRect.Bottom - messageBoxRect.Top)/2)); 

       NativeMethods.SetWindowPos(wParam, 0, xPos, yPos, 0, 0, 0x1 | 0x4 | 0x10); 
       NativeMethods.UnhookWindowsHookEx(messageHook); 
      } 

      return 0; 
     } 
    } 

    private static class NativeMethods 
    { 
     internal struct RECT 
     { 
      public int Left; 
      public int Top; 
      public int Right; 
      public int Bottom; 
     } 

     internal delegate int CenterMessageCallBackDelegate(int message, int wParam, int lParam); 

     [DllImport("user32.dll")] 
     [return: MarshalAs(UnmanagedType.Bool)] 
     internal static extern bool UnhookWindowsHookEx(int hhk); 

     [DllImport("user32.dll", SetLastError = true)] 
     internal static extern int GetWindowLong(IntPtr hWnd, int nIndex); 

     [DllImport("kernel32.dll")] 
     internal static extern int GetCurrentThreadId(); 

     [DllImport("user32.dll", SetLastError = true)] 
     internal static extern IntPtr SetWindowsHookEx(int hook, CenterMessageCallBackDelegate callback, IntPtr hMod, int dwThreadId); 

     [DllImport("user32.dll")] 
     [return: MarshalAs(UnmanagedType.Bool)] 
     internal static extern bool SetWindowPos(int hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags); 

     [DllImport("user32.dll")] 
     [return: MarshalAs(UnmanagedType.Bool)] 
     internal static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect); 
    } 
} 
+0

你忘了說*你從哪裏盜取了這段代碼。歸因在這裏很重要。谷歌搜索出現了幾個可能的來源:http://www.jasoncarr.com/technology/centering-a-message-box-on-the-active-window-in-csharp,http://code.google的.com/p/lioneditor /源極/瀏覽/支鏈/ imageEditorv2/FFTPatcher/PatcherLib/MyMessageBox.cs?規格= svn468&R = 468。 – 2011-04-11 08:22:02

+0

好主意。但請介意你的話:「偷」是一個苛刻的表達。我明確表示「找到其他地方」,但你對歸因絕對正確。 – 2011-04-13 12:58:42

+0

不,原來的代碼並沒有出現在你添加的鏈接上。它來自賈森卡爾:http://www.jasoncarr.com/technology/centering-a-message-box-on-the-active-window-in-csharp。我只是修改它在WPF中工作。謝謝傑森。 – 2011-04-13 17:06:02