MessageBox, NC 23 и Astra Linux
Есть у меня в проекте некий сервис для сообщений - информационных, об ошибках, об исключениях, консольные сообщения - все вот это вот. Поскольку разработка вынужденно ведется в Windows (да и NC на самом деле работает под Wine), я стал использовать стандартные System.Windows.MessageBox. Но вот к поведению этих окон в Linux я оказался совсем не готов.
К примеру, есть метод сообщения об ошибке:
1 2 3 4 5 | public void ErrorMessage(string Message, [CallerMemberName] string CallMethodName = null) { MessageBox.Show(CallMethodName == null ? Message : """ + CallMethodName + "" вызвал ошибку\n" + Message, "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error); } |
Что же здесь может пойти не так? А вот! NC под Linux при таком подходе может MessageBox-то показать, и сразу его скрыть за собою. При этом MessageBox а) не показывается в панели задач (ну или как это там называется); б) по Alt+Tab на него не перейти и в) окно NC очень странно блокируется: выбирать примитивы можно, а вот ни одну команду выполнить не получится. Вываливается сообщение типа "выполнение команды невозможно, пока не завершится предыдущая" (цитирую по памяти).
Полдня экспериментов привели к тому, что в классе, отвечающем за показ MessageBox (а если есть какой-то класс, который будет показывать окна / формы WPF, то и в нем, скорее всего) пришлось добавить:
1 2 | [System.Runtime.InteropServices.DllImport("user32.dll")] private static extern bool SetForegroundWindow(IntPtr hWnd); |
Не забыть объявить переменную уровня класса:
1 | private IntPtr _handle; |
И инициализировать ее в конструкторе (как один из вариантов):
1 | _handle = HostMgd.ApplicationService.Application.MainWindow.Handle; |
И в таком случае вызов ErrorMessage становится чуть-чуть подлиннее:
1 2 3 4 5 6 7 | public void ErrorMessage(string Message, [CallerMemberName] string CallMethodName = null) { if (_handle != IntPtr.Zero) SetForegroundWindow(_handle); MessageBox.Show(CallMethodName == null ? Message : """ + CallMethodName + "" вызвал ошибку\n" + Message, "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error); } |
Что и где не дописали / не допилили, я не знаю. Но использовать, похоже, придется (( Благо под Windows вроде бы поведение не разваливается...
Хотя это выглядит дико, согласен: под линуксом использовать библиотеки винды.
P.S. Шпаргалка, профи, уворачиваться - ничего не меняется
На днях делал финт ушами , чтобы openfiledialog не прятался ,
Он аналогично по умолчанию не умеет topmost
Возможно такой финт прокатит ?
MessageBox.Show(new Form { TopMost = true }, "Hello, I'm on top!");
Побочный эффект после закрытия диалога, теряется фокус
Я не люблю WinForms, у меня там постоянно проблемы с биндингом данных.
А ты точно MessageBox из System.Windows используешь, а не из System.Windows.Forms?
Я этот пример не проверял.
Я таким образом использовал с ofd, чтобы он под консолью не прятался (знаю, что так не используют)))
Просто одна из перегрузок этих окошек умеет принимать параметром хэндл, наверное можно передать this если из окна вызов
А, блин, я напутал... Это в System.Windows.Forms MessageBox'ы не имеют такой перегрузки, но в System.Windows - имеют. Тогда да, можно и хендл окна nanoCAD передавать ) Ну, точнее, попробовать. Если не забуду - завтра проверю, что из этого получится