MessageBox.Show () - PullRequest
       4

MessageBox.Show ()

7 голосов
/ 27 октября 2009

Я хотел бы показать свое окно сообщений в центре его родительской формы. если я перемещаю форму и показываю окно сообщения, оно всегда отображается в центре рабочего стола. Я хочу, чтобы он появился вместе с формой. Можете ли вы дать мне несколько хитростей и советов?

Ответы [ 5 ]

3 голосов
/ 27 октября 2009

Лучший способ сделать это - использовать Window Hooks и центрировать окно сообщения самостоятельно. Есть отличная статья, которая показывает это использование.

Вы можете найти его здесь: http://www.codeproject.com/KB/dialog/CenterDialog.aspx

Вы также можете использовать класс в своем приложении, не углубляясь слишком глубоко, чтобы узнать, как он на самом деле работает.

2 голосов
/ 27 октября 2009

Установите владельца окна окна сообщения в ваше окно (используя первый параметр .Show()), вместо того, чтобы не устанавливать владельца.

См. здесь для справки.

1 голос
/ 11 апреля 2011

Я создал этот класс на основе класса для Windows Forms, который я нашел где-то еще.

Просто добавьте класс в ваш проект WPF и укажите «this» в качестве параметра вспомогательного метода следующим образом:

  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);
    }
}
1 голос
/ 27 октября 2009

Я делал это раньше в C #. Вот что я помню.

Определите класс:

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

    public IntPtr Handle
    {
        get; 
        set;
    }
}

Определить класс на основе MessageBox. Создайте класс на основе MessageBox и создайте новый метод Show:

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

}

В вашем коде вызова (здесь предполагается, что это winform, а msgBox основан на новом классе окна сообщений), вызовите новый метод Show и передайте экземпляр IWindowWrapper в Show, например.

msgBox.Show(new IWindowWrapper(this.Handle))
0 голосов
/ 09 февраля 2011

Это очень простое в использовании решение, которое отлично работает:

Шаги:

  1. Скопируйте и вставьте этот класс в ваш проект. Я использовал его без редактирования.
  2. Чтобы использовать измененный MessageBox, используйте следующую строку кода в вашем проекте:

(внутри UserControl или Form)

MessageBoxEx.Show(this, "Please fix the validation errors before saving.", "Validation Errors");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...