Jun 22

.NET und immer wieder Spaß beim Drucken

Tag: Tipps und TricksTorsten @ 20:22

Ich habe mich die letzten Tage mal wieder mit Drucken in .NET beschäftigt und habe dabei wieder festestellen müssen, dass Probleme, die schon seit langem bekannt sind, nach wie vor vorhanden sind.

1) PrintDialog und die x64 Welt…

Wer kennt ihn nicht, den guten alten Drucken-Dialog.

PrintDialog

PrintDialog

Eigentlich denkt man sich, hier kann man nicht viel falsch machen.

PrintDialog pd = new PrintDialog();
pd.Document = myPrintDocument;
var result = pd.ShowDialog();

Das funktioniert auch alles wunderbar – solange man entweder in x86; oder aber auf AnyCPU kompiliert und die Anwendung auf einem 32-Bit Betriebssystem ausführt. Aber wehe, man kommt auf die Idee etwas x64 oder AnyCPU-kompiliertes auf einem 64-Bit Betriebssystem aufrufen zu wollen. Denn dann passiert beim Aufruf von ShowDialog() nämlich überhaupt nichts

Es gibt ein Workaround:

pd.UseEXDialog = true;

Damit wird der alte XP Style für diesen Dialog verwendet und dann wird das Drucken Dialogfenster auch unter x64 korrekt aufgerufen:

Drucken-Dialog XP Style

Drucken-Dialog XP Style

Was wirklich traurig ist, dass dieses Fehlverhalten bereits seit dem .NET 2.0 Framework existiert. Es wurde weder in 3.0, noch in 3.5 oder 3.5 SP1 behoben. Aber: jetzt kommt die gute Nachricht, in .NET 4.0 hat man sich der Problematik endlich angenommen und es funktioniert dort nun auch ohne den XP Style Trick… Das wurde auch Zeit 😉

 

2) PageSetupDialog und die metrische Welt

Seite einrichten Dialog

Seite einrichten Dialog

Auch beim PageSetupDialog denkt sich vielleicht der ein oder andere, dass man nicht viel verkehrt machen kann:

PageSetupDialog psd = new PageSetupDialog();
pd.Document = myPrintDocument;

Das funktioniert auch einwandfrei, aber wenn man nun den Dialog nacheinander mehrmals startet und mit OK bestätigt, werden die Ränder bei jedem mal kleiner, obwohl man keinerlei Änderungen (Links / Oben / Rechts / Unten) gemacht hat. Grund ist ein interner Umrechnungs-Fehler.

Das Problem ist seit langem bekannt, es gibt sogar einen Microsoft KnowledgeBase Artikel zu dieser Problematik: BUG: The margin value decreases every time PageSetupDialog is displayed.

Es wird darin allen Ernstes empfohlen, dass der Benutzer der Anwendung die Regionaleinstellungen seines Betriebssystems auf das Angloamerikanische Maßsystem umstellen soll, um den Fehler zu umgehen. Wenn man das aus Sicht des Entwicklers liest, fragt man sich aber, ob das so wirklich Sinn macht… *g

Andere Entwickler sahen das auch so und haben sich das ein oder andere dazu einfallen lassen, siehe z.B. hier in einem Artikel von 2004 über VB .NET, in dem eine Korrektur-Umrechnungsformel entwickelt wurde.

Was aber wirklich hilft, und auf was Microsoft eigentlich auch viel eher in ihrer KnowledgeBase hinweisen sollte, ist:

psd.EnableMetric = true;

Damit werden die Werte der Ränder auf einem metrischen System auch von Anfang an korrekt 1:1 angezeigt und nicht umgerechnet. Es empfiehlt sich, dieses Flag fallweise auf Grund der aktuell eingestellten Regionseinstellungen zu setzen, damit die Anwendung wirklich international funktioniert, also konkret:

psd.EnableMetric = System.Globalization.RegionInfo.CurrentRegion.IsMetric

 

PS: Diese „spezielle“ Verhalten ist bis einschließlich .NET 4.0 vorhanden, ich denke mal Microsoft sieht das nicht als Fehler, da es im amerikanischen Raum eh nicht auftritt – und wer für Europa programmiert, muss das halt einfach wissen. 🙂