私のWPFアプリでWindow
は、他のコントロールの中でも、DocumentViewer
.
このウィンドウを開いてロードするFixedDocument
と、進行状況インジケータを含む が動的に作成され、 に表示されますDocumentViewer
。これは機能し、ユーザー エクスペリエンスを向上させるために、このウィンドウを独自のスレッドで実行して、ドキュメントの作成中にメイン アプリケーション ウィンドウが応答するようにします。
この Web ページのヒントに基づいて、次のような新しいスレッドでウィンドウを開きます。
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)
...
私の推測では、メインの UI スレッドで印刷ダイアログが開いていて、自分のスレッドによって作成および所有されているドキュメントにアクセスしようとしているため、クラッシュしています。
これを解決する方法はありますか?ウィンドウを独自のスレッドに保持したいと思います。