Проблема:
При открытии модального окна WPF (Window.ShowDialog()) из основного потока WinForms окно иногда открывается полностью белым/пустым.
- Граница окна и строка заголовка видны.
- Область содержимого белая.
- Важное наблюдение: кажется, что логическое дерево существует (курсор меняется на двутавровое над текстовыми полями, стрелка над кнопками), но ничего не отображается.
- Обходное решение: Если я вручную изменяю размер окна, перетаскивая границу, содержимое мгновенно появляется.
Проблема воспроизводится только после определенного сложного сценария, включающего открытие/закрытие нескольких гибридных окон и активных фоновых потоков (агент данных, Messenger). Это похоже на недостаточность насоса сообщений или тупик макета между WinForms и диспетчерами WPF.
Что я установил на данный момент:
- Нет исключений: В окне вывода нет необработанных исключений. Раньше у меня был спам InvalidOperationException (межпоточный доступ), но я исправил его, защитив периодические/фоновые обновления пользовательского интерфейса. Журнал чист.
- Это не утечка GDI: Количество объектов GDI низкое (~ 200).
- Это не проблема с драйвером: Я принудительно включил System.Windows.Interop.RenderMode.SoftwareOnly, но белое окно остается.
- "Ударить" окно: Добавлен код в событии Loaded для InvalidateVisual(), UpdateLayout() и программно изменить ширину на 0,1 пикселя через Dispatcher.BeginInvoke (с различными приоритетами: Loaded, Render, ContextIdle).
- Результат: Программное изменение размера не дает никаких результатов. Работает только физическое изменение размера мыши.
- Z-Order/Topmost: Явно задайте Topmost = false, чтобы избежать проблем с воздушным пространством.
- Очистка очередей: Перед вызовом .ShowDialog() я попробовал вызвать System.Windows.Forms.Application.DoEvents() и WpfApplication.Current.Dispatcher.Invoke(...) для очистки ожидающих сообщений.
- Предварительная инициализация: попробовала последовательность обеспеченияHandle(), Show(), Hide() перед ShowDialog(), чтобы принудительно создать базовую поверхность HWND и DirectX.
- Удаление SizeToContent: Подозревался конфликт между SizeToContent и настройкой размера вручную в Loaded, но его удаление не решило проблему с голоданием.
и другими попытками бесконечности.
Метод, используемый для открытия окна WPF из WinForms:
код C#
Код: Выделить всё
public static bool ShowContextedWindow(object viewModel)
{
var win = new DialogWindow()
{
Content = viewModel,
DataContext = viewModel,
WindowStartupLocation = WindowStartupLocation.CenterScreen,
Topmost = false
};
var helper = new WindowInteropHelper(win);
helper.Owner = System.Windows.Forms.Form.ActiveForm.Handle;
ElementHost.EnableModelessKeyboardInterop(win);
System.Windows.Forms.Application.DoEvents();
return win.ShowDialog() == true;
}
Почему конвейер рендеринга WPF зависает (не может обработать WM_PAINT?) при модальном открытии из WinForms под нагрузкой, и почему программное изменение размера не может его разбудить, в то время как изменение размера вручную работает? Существуют ли специальные «ядерные параметры», позволяющие диспетчеру WPF обрабатывать очередь рендеринга в этом конкретном сценарии гибридной взаимоблокировки?
Подробнее здесь: https://stackoverflow.com/questions/798 ... pplication
Мобильная версия