2009-02-19 25 views
17

Tôi có bài đăng WPF 700w x 300h và có thể kéo nó ở bất cứ đâu trên màn hình lớn của tôi.Cách nhận MessageBox.Show() để bật lên ở giữa ứng dụng WPF của tôi?

Khi ứng dụng của tôi thực hiện:

hộp
MessageBox.Show("Sorry, this function is not yet implemented."); 

các mesage xuất hiện ở giữa màn hình của tôi , mà có thể hoặc thậm chí không thể được ở gần bản thân ứng dụng.

Làm cách nào để tôi có thể nhận Hộp thư của mình xuất hiện ở giữa ứng dụng thay thế?

+2

Edward, bạn có thể giải quyết vấn đề này không? Tôi đã thử bằng cách sử dụng Application.Current.MainWindow nhưng không có hiệu lực, Hộp thư vẫn tập trung trong màn hình chứ không phải cửa sổ ứng dụng WPF chính của tôi. – byte

+0

Đây là một tham chiếu đến một luồng lưu trữ Q & A thực sự hoạt động (đối với tôi) http://stackoverflow.com/questions/1629213/messagebox-show – invalidusername

Trả lời

-9

Nếu ứng dụng của bạn có nhiều cửa sổ, bạn có thể muốn sử dụng Application.Current.MainWindow:

MessageBox.Show(Application.Current.MainWindow, "Can't login with given names.", "Login Failure", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.Cancel); 
+15

Điều này có thực sự hoạt động không? Nó không làm điều đó cho tôi – Karsten

+2

Câu trả lời này không làm những gì OP yêu cầu. –

+2

Điều này không tập trung vào MessageBox vào Cửa sổ Chính, chỉ đảm bảo rằng nó nằm trước Cửa sổ Chính. câu trả lời – Curtis

6

Đây là answered here for Windows.Forms nhưng với những sản phẩm sau được bổ sung vào lớp học của bạn, bạn có thể lấy nó để làm việc trong WPF.

Bạn phải thêm tham chiếu đến System.Windows.Forms & System.Drawing để lớp ở trên hoạt động và thực hiện các thao tác sau.

public partial class YourWPFWindow : Window, System.Windows.Forms.IWin32Window 
{ 
    public IntPtr Handle 
    { 
     get { return new WindowInteropHelper(this).Handle; } 
    } 
} 

Sau đó, bạn có thể gọi MessageBoxEx với:

MessageBoxEx.Show(this, "Message"); 

Nó sẽ hiện lên ở giữa cửa sổ của bạn.

+0

này nên được đánh dấu câu trả lời đúng – msnider

14

Dưới đây là một phiên bản của lớp helper MessageBoxEx đăng trong chủ đề khác có sử dụng hộp thư phong cách WPF (Lưu ý rằng bạn vẫn cần phải tham khảo System.Drawing):

using System; 
using System.Text; 
using System.Runtime.InteropServices; 
using System.Windows; 
using System.Windows.Interop; 
using System.Drawing; 

public class MessageBoxEx 
{ 
    private static IntPtr _owner; 
    private static HookProc _hookProc; 
    private static IntPtr _hHook; 

    public static MessageBoxResult Show(string text) 
    { 
     Initialize(); 
     return MessageBox.Show(text); 
    } 

    public static MessageBoxResult Show(string text, string caption) 
    { 
     Initialize(); 
     return MessageBox.Show(text, caption); 
    } 

    public static MessageBoxResult Show(string text, string caption, MessageBoxButton buttons) 
    { 
     Initialize(); 
     return MessageBox.Show(text, caption, buttons); 
    } 

    public static MessageBoxResult Show(string text, string caption, MessageBoxButton buttons, MessageBoxImage icon) 
    { 
     Initialize(); 
     return MessageBox.Show(text, caption, buttons, icon); 
    } 

    public static MessageBoxResult Show(string text, string caption, MessageBoxButton buttons, MessageBoxImage icon, MessageBoxResult defResult) 
    { 
     Initialize(); 
     return MessageBox.Show(text, caption, buttons, icon, defResult); 
    } 

    public static MessageBoxResult Show(string text, string caption, MessageBoxButton buttons, MessageBoxImage icon, MessageBoxResult defResult, MessageBoxOptions options) 
    { 
     Initialize();    
     return MessageBox.Show(text, caption, buttons, icon, defResult, options); 
    } 

    public static MessageBoxResult Show(Window owner, string text) 
    { 
     _owner = new WindowInteropHelper(owner).Handle; 
     Initialize(); 
     return MessageBox.Show(owner, text); 
    } 

    public static MessageBoxResult Show(Window owner, string text, string caption) 
    { 
     _owner = new WindowInteropHelper(owner).Handle; 
     Initialize(); 
     return MessageBox.Show(owner, text, caption); 
    } 

    public static MessageBoxResult Show(Window owner, string text, string caption, MessageBoxButton buttons) 
    { 
     _owner = new WindowInteropHelper(owner).Handle; 
     Initialize(); 
     return MessageBox.Show(owner, text, caption, buttons); 
    } 

    public static MessageBoxResult Show(Window owner, string text, string caption, MessageBoxButton buttons, MessageBoxImage icon) 
    { 
     _owner = new WindowInteropHelper(owner).Handle; 
     Initialize(); 
     return MessageBox.Show(owner, text, caption, buttons, icon); 
    } 

    public static MessageBoxResult Show(Window owner, string text, string caption, MessageBoxButton buttons, MessageBoxImage icon, MessageBoxResult defResult) 
    { 
     _owner = new WindowInteropHelper(owner).Handle; 
     Initialize(); 
     return MessageBox.Show(owner, text, caption, buttons, icon, defResult); 
    } 

    public static MessageBoxResult Show(Window owner, string text, string caption, MessageBoxButton buttons, MessageBoxImage icon, MessageBoxResult defResult, MessageBoxOptions options) 
    { 
     _owner = new WindowInteropHelper(owner).Handle; 
     Initialize(); 
     return MessageBox.Show(owner, text, caption, buttons, icon, 
           defResult, options); 
    } 

    public delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam); 

    public delegate void TimerProc(IntPtr hWnd, uint uMsg, UIntPtr nIDEvent, uint dwTime); 

    public const int WH_CALLWNDPROCRET = 12; 

    public enum CbtHookAction : int 
    { 
     HCBT_MOVESIZE = 0, 
     HCBT_MINMAX = 1, 
     HCBT_QS = 2, 
     HCBT_CREATEWND = 3, 
     HCBT_DESTROYWND = 4, 
     HCBT_ACTIVATE = 5, 
     HCBT_CLICKSKIPPED = 6, 
     HCBT_KEYSKIPPED = 7, 
     HCBT_SYSCOMMAND = 8, 
     HCBT_SETFOCUS = 9 
    } 

    [DllImport("user32.dll")] 
    private static extern bool GetWindowRect(IntPtr hWnd, ref Rectangle lpRect); 

    [DllImport("user32.dll")] 
    private static extern int MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint); 

    [DllImport("User32.dll")] 
    public static extern UIntPtr SetTimer(IntPtr hWnd, UIntPtr nIDEvent, uint uElapse, TimerProc lpTimerFunc); 

    [DllImport("User32.dll")] 
    public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam); 

    [DllImport("user32.dll")] 
    public static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId); 

    [DllImport("user32.dll")] 
    public static extern int UnhookWindowsHookEx(IntPtr idHook); 

    [DllImport("user32.dll")] 
    public static extern IntPtr CallNextHookEx(IntPtr idHook, int nCode, IntPtr wParam, IntPtr lParam); 

    [DllImport("user32.dll")] 
    public static extern int GetWindowTextLength(IntPtr hWnd); 

    [DllImport("user32.dll")] 
    public static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int maxLength); 

    [DllImport("user32.dll")] 
    public static extern int EndDialog(IntPtr hDlg, IntPtr nResult); 

    [StructLayout(LayoutKind.Sequential)] 
    public struct CWPRETSTRUCT 
    { 
     public IntPtr lResult; 
     public IntPtr lParam; 
     public IntPtr wParam; 
     public uint message; 
     public IntPtr hwnd; 
    } ; 

    static MessageBoxEx() 
    { 
     _hookProc = new HookProc(MessageBoxHookProc); 
     _hHook = IntPtr.Zero; 
    } 

    private static void Initialize() 
    { 
     if (_hHook != IntPtr.Zero) 
     { 
      throw new NotSupportedException("multiple calls are not supported"); 
     } 

     if (_owner != null) 
     { 
      _hHook = SetWindowsHookEx(WH_CALLWNDPROCRET, _hookProc, IntPtr.Zero, AppDomain.GetCurrentThreadId()); 
     } 
    } 

    private static IntPtr MessageBoxHookProc(int nCode, IntPtr wParam, IntPtr lParam) 
    { 
     if (nCode < 0) 
     { 
      return CallNextHookEx(_hHook, nCode, wParam, lParam); 
     } 

     CWPRETSTRUCT msg = (CWPRETSTRUCT)Marshal.PtrToStructure(lParam, typeof(CWPRETSTRUCT)); 
     IntPtr hook = _hHook; 

     if (msg.message == (int)CbtHookAction.HCBT_ACTIVATE) 
     { 
      try 
      { 
       CenterWindow(msg.hwnd); 
      } 
      finally 
      { 
       UnhookWindowsHookEx(_hHook); 
       _hHook = IntPtr.Zero; 
      } 
     } 

     return CallNextHookEx(hook, nCode, wParam, lParam); 
    } 

    private static void CenterWindow(IntPtr hChildWnd) 
    { 
     Rectangle recChild = new Rectangle(0, 0, 0, 0); 
     bool success = GetWindowRect(hChildWnd, ref recChild); 

     int width = recChild.Width - recChild.X; 
     int height = recChild.Height - recChild.Y; 

     Rectangle recParent = new Rectangle(0, 0, 0, 0); 
     success = GetWindowRect(_owner, ref recParent); 

     System.Drawing.Point ptCenter = new System.Drawing.Point(0, 0); 
     ptCenter.X = recParent.X + ((recParent.Width - recParent.X)/2); 
     ptCenter.Y = recParent.Y + ((recParent.Height - recParent.Y)/2); 


     System.Drawing.Point ptStart = new System.Drawing.Point(0, 0); 
     ptStart.X = (ptCenter.X - (width/2)); 
     ptStart.Y = (ptCenter.Y - (height/2)); 

     ptStart.X = (ptStart.X < 0) ? 0 : ptStart.X; 
     ptStart.Y = (ptStart.Y < 0) ? 0 : ptStart.Y; 

     int result = MoveWindow(hChildWnd, ptStart.X, ptStart.Y, width, 
           height, false); 
    } 
} 
+1

này hoạt động tuyệt vời mặc dù tôi không chắc chắn lý do tại sao ' ptStart.X = (ptStart.X <0)? 0: ptStart.X; ' ' ptStart.Y = (ptStart.Y <0)? 0: ptStart.Y; 'nằm trong' CenterWindow (IntPtr hHhildWnd) 'như thể người dùng có nhiều màn hình và có màn hình chính của mình như một thứ khác ngoài phần lớn ứng dụng có thể có trong âm bản và bạn sẽ muốn hộp thông báo hiển thị trong vị trí x âm nếu không nó sẽ không xuất hiện ở trung tâm của ứng dụng nếu nó nằm trên màn hình bên trái của chính hoặc dưới nó cho vấn đề đó liên quan đến việc cần một y âm. – Birdbuster

+0

@Birdbuster đã làm nó thực sự làm việc cho bạn? Tôi đã thử điều này và hộp thông báo luôn xuất hiện ở trên cùng bên trái của màn hình của tôi (không phải cửa sổ) – Mirza

+0

@Mirza Có hoàn toàn làm việc cho tôi. Bạn đang sử dụng các phiên bản mà bạn vượt qua trong cửa sổ chủ sở hữu phải không? Có vẻ như là một câu hỏi ngớ ngẩn nhưng có lẽ chỉ là một cái nhìn quá rõ ràng về phía bạn? Tôi cũng sửa đổi void tĩnh tư nhân CenterWindow (IntPtr hChildWnd) {} như đã nêu trong bình luận của tôi để nếu cửa sổ của tôi là trong trục x hoặc y tiêu cực liên quan đến cửa sổ "chính" màn hình nó vẫn hiển thị ở giữa chính xác. – Birdbuster

0

Ngoài Framnk's answer

phần này không hoạt động trên nhiều màn hình

ptStart.X = (ptStart.X < 0) ? 0 : ptStart.X; 
ptStart.Y = (ptStart.Y < 0) ? 0 : ptStart.Y; 

đây là một QuickFix:

var allScreens = System.Windows.Forms.Screen.AllScreens; 
ptStart.X = allScreens.All(a => a.WorkingArea.Left > ptStart.X) ? allScreens.Min(a => a.WorkingArea.Left) : ptStart.X; 
ptStart.X = allScreens.All(a => a.WorkingArea.Right - width < ptStart.X) ? allScreens.Max(a => a.WorkingArea.Right) - width : ptStart.X; 
ptStart.Y = allScreens.All(a => a.WorkingArea.Top > ptStart.Y) ? allScreens.Min(a => a.WorkingArea.Top) : ptStart.Y; 
ptStart.Y = allScreens.All(a => a.WorkingArea.Bottom - height < ptStart.Y) ? allScreens.Max(a => a.WorkingArea.Bottom) - height : ptStart.Y; 
1

Một cách tiếp cận khác là tạo cửa sổ hộp thư của riêng bạn và đặt vị trí khởi động của cửa sổ thành chủ sở hữu trung tâm. Ưu điểm là bạn có thể dễ dàng có phong cách và tùy chỉnh của mình mà không cần phải gắn kết.

+0

bạn nên cung cấp mã tối thiểu để hỗ trợ câu trả lời của bạn. những gì bạn đã bao giờ đăng ở đây, mà có thể đi như một bình luận nhưng không phải là một câu trả lời. – Raju

Các vấn đề liên quan