По итогу я решил свою проблему следующим способом:
- Создал окно WPF с разметкой из одного требуемого мне контрола - полной копией того, что в основном окне.
Создание этого окна сделал в отдельном потоке, отображал окно с помощью ShowDialog() так как он не дает потоку завершиться раньше времени.
Thread hidePrintThread = new Thread(PrintMethod);
hidePrintThread.SetApartmentState(ApartmentState.STA);
hidePrintThread.IsBackground = true;
hidePrintThread.Start();
void PrintMethod()
{
try
{
CriteriaOperator co=null;
List<MessageGridContent> mess = Service.Messages.ToList();
Dispatcher.Invoke(() => co = messageGrid.FilterCriteria);
HiddenPrintWindow window = new HiddenPrintWindow();
window.MessagesToPrint = mess;
window.CriteriaOperator = co;
Service.Printing = true;
window.ShowDialog();
}
catch(Exception ex)
{
logger.Error("Ошибка печати: {0}", ex.Message);
}
}
Так как мне необходимо было, чтобы данная длительная операция проходила незаметно для пользователя, я решил скрыть окно. Стандартные методы работать отказывались. Я пробовал прописывать Visibyliti в разметке, пробовал в обработчике события загрузки окна, пробовал в методе, который запускается из обработчика загрузки, но окно упрямо висело видимым, тогда я убрал его на задний план (тоже подходило по ТЗ) с помощью WinAPI:
[DllImport("user32.dll")]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
Код инициализации и загрузки самого окна:
public HiddenPrintWindow()
{
InitializeComponent();
Loaded += HiddenPrintWindow_Loaded;
}
private void HiddenPrintWindow_Loaded(object sender, RoutedEventArgs e)
{
SetWindowPos(new System.Windows.Interop.WindowInteropHelper(this).Handle, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
Work();
}
И спасибо всем помогавшим!!!
Dispatcher.Invoke()и все равно UI будет заблокирован – Ivan Kozlov Oct 11 '18 at 12:51messageView- элемент UI, доступ к нему из фонового потока не получить без использованияDispatcherтого же потока, в котором он был создан, следовательно, и вся операция будет выполняться в основном GUI-потоке и все встанет колом, пока не выполнится – Ivan Kozlov Oct 11 '18 at 13:10Task.Factory.StartNewне поможет по тем же самым причинам – tym32167 Oct 11 '18 at 13:15Dispatcher. Разбивайте ваш метод печати на мелкие части и выполняйте их последовательно какDispatcherOperationчерезDispatcherUI-потока, при этом не забывая даватьDispatcherу выполнять другие операциии, чтобы UI не выглядел зависшим. – dymanoid Oct 11 '18 at 13:36Dispatcherи тот же UI-поток (если специально не создавать окно с другимDispatcherи в другом потоке - но в этом случае контрол нельзя будет "перетащить" из первого окна во второе во время выполнения). – dymanoid Oct 11 '18 at 13:38