В моем приложении WPF у меня есть конкретный Window
, который содержит, помимо других элементов управления, DocumentViewer
.
Когда это окно открывается и загружается, оно динамически создает FixedDocument
с индикатором прогресса, а затем отображает его в DocumentViewer
. Это работает, и для улучшения взаимодействия с пользователем я запускаю это окно в своем собственном потоке, чтобы главное окно приложения все еще реагировало во время создания документа.
Исходя из советов на этой веб-странице , я открываю окно в новой теме, например:
public void ShowDocumentViewerWindow(params object[] data) {
var thread = new Thread(() => {
var window = new MyDocumentViewerWindow(new MyObject(data));
window.Closed += (s, a) => window.Dispatcher.InvokeShutdown();
window.Show();
System.Windows.Threading.Dispatcher.Run();
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
До сих пор я был доволен этой настройкой, но я только что столкнулся с проблемой.
MyDocumentViewerWindow
содержит кнопку печати, которая ссылается на встроенную команду печати, предназначенную для DocumentViewer:
<Button Command="Print" CommandTarget="{Binding ElementName=MyDocumentViewer}">Print</Button>
До того, как у меня было окно в собственном потоке, это работало нормально. Но теперь, когда я нажимаю на него, приложение вылетает. Visual Studio 2010 выделяет следующую строку из приведенного выше кода в качестве места сбоя с сообщением « Вызывающий поток не может получить доступ к этому объекту, поскольку он принадлежит другому потоку. »:
System.Windows.Threading.Dispatcher.Run();
Трассировка стека начинается так:
at System.Windows.Threading.Dispatcher.VerifyAccess()
at MS.Internal.Printing.Win32PrintDialog.ShowDialog()
at System.Windows.Controls.PrintDialog.ShowDialog()
at System.Printing.PrintQueue.GatherDataFromPrintDialog(PrintDialog printDialog, XpsDocumentWriter&amp; writer, PrintTicket&amp; partialTrustPrintTicket, PrintQueue&amp; partialTrustPrintQueue, Double&amp; width, Double&amp; height, String jobDescription)
at System.Printing.PrintQueue.CreateXpsDocumentWriter(String jobDescription, PrintDocumentImageableArea&amp; documentImageableArea)
at System.Windows.Controls.Primitives.DocumentViewerBase.OnPrintCommand()
at System.Windows.Controls.Primitives.DocumentViewerBase.ExecutedRoutedEventHandler(Object target, ExecutedRoutedEventArgs args)
...
Я догадываюсь, что диалоговое окно печати открывается в главном потоке пользовательского интерфейса и пытается получить доступ к документу, созданному и принадлежащему моему собственному потоку, что приводит к сбою.
Есть идеи, как мне это решить? Я хотел бы сохранить окно в своей собственной теме.