I am using a C1ReportViewer control, and have already posted a question on the C1 forums, however i thought i would post here as well to see if anyone had run across a similar issue. The control uses the generic silverlight PrintDocument() method.
When printing a Crystal Report from this control in Silverlight 5 sometimes the report prints out garbled, meaning different sized text, tapered lines and generally out of position. It also rarely prints the entire report.
I have narrowed the issue down to a few printers, and only with machines using their 32 bit drivers. Based upon this, and the changes made to Silverlight 5, i am assuming the issue revolves around PostScript compatibility. However, as our product is LOB application, enforcing PS compatible printers and printer drivers is nearly out of the question.
Accordingly, if this is indeed a post script issue, based upon the documentation for silverlight 5, the PrintDocument() method should be failing back to the default bitmap method. See Am I correct in understanding that vector printing in SilverLight 5 will only work with a Postscript printer?
My question for stackoverflow is: Has anyone encountered a similar issue in with printing in Silverlight 5, or has anyone had success printing Crystal Reports/PDFs? And in the off chance that anyone has, what solutions have you come up with?
Much Appreciated,
Greg
I was able to come up with a solution for this. Instead of using the built in C1 Printing functionality I was able to write some code to force bitmap printing.
First i created a new PrintDocument, and hooked up some handlers for its PrintPage event.
mobjPrintDocument = New PrintDocument
RemoveHandler mobjPrintDocument.PrintPage, AddressOf Print_Report
AddHandler mobjPrintDocument.PrintPage, AddressOf Print_Report
Then we can call the PrintBitmap function on the PrintDocument whenever you want to print. Here I am doing it when the user clicks the Print button.
Private Sub xbtnPrint_Click(sender As System.Object, e As System.Windows.RoutedEventArgs)
mintPageIndex = 0
mobjPrintDocument.PrintBitmap(FileName)
End Sub
Now comes the important part. We can hijack the content targeted by hooking into the PrintPage event (as handled above). I can set the e.PageVisual to any visual xaml element and the PrintBitmap will handle it. Here I use the GetPages function and loop through to make sure I print each page (a pdfviewer element). However, you can point it to any visual element like I said.
Private Sub Print_Report(sender As System.Object, e As PrintPageEventArgs)
e.PageVisual = xobjReportViewer.GetPages(mintPageIndex)
mintPageIndex += 1
e.HasMorePages = mintPageIndex < xobjReportViewer.GetPages.Count
End Sub
The e.HasMorePages allows you to force the firing of this event until you are finished.
Hope this is helpful to someone. With Silverlight 5 and the Post-Script printer support, alot of printers that have a PostScript emulator may not be compatible, but will also not default to bitmap printing. This workaround fixes that, making printing a little bit more stable in a LOB type application.
Related
I am working on a wpf project...I've faced similar issues in the past,but didn't get the answer to it and that's why i'm asking again :)
My WPF app has 2 windows,one works as a splash screen and the 2nd one is just a basic window with a canvas.The splash screen has a BackGroundWorker.Now,i have this code :
Dim h2 as new Window2
For Each fi As FileInfo In New DirectoryInfo(Application.StartupPath +
"\data\img\em_sml").GetFiles()
h2.canvas.children.add(new Button)
Now, my question is how do i use this code in the backgroundworker in Window1 ?? I tried this :
Dim method as Delegate
Private Sub BgWorker_DoWork(sender As Object, e As DoWorkEventArgs) Handles BgWorker.DoWork
If h2.Dispatcher.CheckAccess Then
For Each fi As FileInfo In New DirectoryInfo(Application.StartupPath +
"\data\img\em_sml").GetFiles()
h2.canvas.children.add(new Button)
Else
h2.Dispatcher.BeginInvoke(DispatcherPriority.Normal, method)
For Each fi As FileInfo In New DirectoryInfo(Application.StartupPath +
"\data\img\em_sml").GetFiles()
h2.canvas.children.add(new Button)
End if
A few things i'ld like to clear here :
• I got the sample code from another SO post(i converted it from c#)
• Dim method as Delegate,i don't really know how to use a delegate function
• The code above returns some exceptions like Parameter name:Method , Value can not be null(I know what this means but as i said,i don't know how i can use the delegate function in such a case)
Any help would be appreciated
The code you're using is trying to invoke to the UI thread via Dispatcher.BeginInvoke(). This is the way to do it in threads, but not in a BackgroundWorker. In a BGW you're supposed to call the ReportProgress() method combined with subscribing to the ProgressChanged event.
However for what you're trying to do, this is not good at all...
For starters: You should NEVER create controls in a background thread! All work related to the UI (User Interface) must always, always, always be done on the UI thread ONLY.
Secondly: There isn't really a good reason for trying to do this in a background thread. The way you're doing it now constantly updates the UI thread, causing it to lag/freeze anyway. What you could do to minimize the lag is to add the buttons in batches, but then as I said before you shouldn't be creating controls in a background thread at all.
Finally: The whole operation of iterating a few files and creating buttons for them really isn't very heavy. Unless you have thousands of files (in which case you should only display them in batches) this will not take that long to perform on the UI thread.
Conclusion: Skip the BackgroundWorker and run your code on the UI thread instead. If you have a really huge amount of files to load, store their paths in a list, only load them in batches and let the user decide when to load the next batch of files.
I'm working on a VB6 project and I cam across something that I'm unable to resolve. In my project I'm using 2.0 comboboxes. Everything works fine, in terms of loading the combobox with data, selecting it, and the whole bunch. What I'm trying to do is, once data has been selected, I'm making sure that the same data has not been selected in both comboboxes. I'm trying to write a quick comparison IF statement in LOST FOCUS for one of the cbo's but it doesn't seem to work.
Private Sub cbo1_LostFocus()
if cbo1.text<>"" and cbo2.text<>"" then
if cbo1.text = cbo2.text then
MSGBOX "Duplicate Values"
else
exit sub
End if
end if
End Sub
it doesn't at all realize there is LOST FOCUS - I don't think I've ever done that to a cbo, usually textboxes and such. Any help is appreciated.
You could try GotFocus instead. It seems the LostFoucs event can be overridden or masked in certain cases. This article shows a similar problem: http://www.vbforums.com/showthread.php?396536-RESOLVED-VB6-LostFocus
Of course, you could always upgrade to the latest VB, but I'm guessing you have your reasons.
I am having a hard time to create an exception handler in a WPF application coded in VB.net.
I already read a tons of articles on the internet, but most of them only work in WindowsForms or are written in C#.
The thing I like is a simple MessageBox with the crash reason when the application is crashing.
I think this here
should be the way to go, but I cannot get it to work, since it seems to be for Windows Forms.
Visual Studio show multiple errors, mainly because it is not finding the UnhandledException event...
I would be really grateful about an explanation how to get the think I try to get.
Edit: Something like this
You're probably looking for Application.DispatcherUnhandledException event.
In App.xaml you need to add a handler for this event:
<Application DispatcherUnhandledException="DispatcherUnhandledExceptionEventHandler" .../>
Then in code behind you can write your code for handling the exception:
Private Sub App_DispatcherUnhandledException(ByVal sender As Object, ByVal e As DispatcherUnhandledExceptionEventArgs)
' Process unhandled exception
e.Handled = True
End Sub
Here you can find more information, even with sample code in Visual Basic.
I have a Winform GUI that have an UDPClient listener thread working on second plane to avoid halt the GUI; when the thread receive something call a Sub in the WinForm code; that Sub process the data and must to fill different TextBox depending on the received data.
As you know if I try to change the text property of any control from the Sub I will receive a Cross Thread error.
So in order to avoid that I make some delegates for a few control(just a test) and works OK.
But the WinForm have more than 100 controls and I was wondering if there's some way to do it with less code.
Making a search I found this two questions.
Multi-threaded WPF Application: Dispatcher Invoke. A more efficient way?
Change WPF controls from a non-main thread using Dispatcher.Invoke
On the first link they talk about use Dispacher, something like
Public Shared Sub UiInvoke(a As Action)
Application.Current.Dispatcher.Invoke(a)
End Sub
I wrote that code in my Form but the IDE(VS2010/NET4.0) says that "Current" is not a member.
I think I'm missing something, I never used before or do something similar as Dispacher, I usually use Delegates.
What I'm doing wrong? There's another way to control many controls with one Delegate?
I just need to read or write the text property.
You can use anonymous Subs:
Me.Invoke(
Sub()
' Update controls here
End Sub)
I have a Silverlight 5 OOB application (with Elevated Permissions) that's just been deployed to a number of our users.
Some of these users are reporting that prints are coming out blank or very faint.
These printers do print Word documents correctly and I am unable to reproduce the problem on my own printers.
All users are on Windows XP SP3 32 bit, and I am developing on Win7 64 bit.
As anyone seen this issue before? Or any idea what could be causing this?
Help much appreciated.
Many Thanks,
Andrew
I Should Got Solution May Be useFull To You.............................
First i created a new PrintDocument, and hooked up some handlers for its PrintPage event.
mobjPrintDocument = New PrintDocument
RemoveHandler mobjPrintDocument.PrintPage, AddressOf Print_Report
AddHandler mobjPrintDocument.PrintPage, AddressOf Print_Report
Then we can call the PrintBitmap function on the PrintDocument whenever you want to print. Here I am doing it when the user clicks the Print button.
Private Sub xbtnPrint_Click(sender As System.Object, e As System.Windows.RoutedEventArgs)
mintPageIndex = 0
mobjPrintDocument.PrintBitmap(FileName)
End Sub
Now comes the important part. We can hijack the content targeted by hooking into the PrintPage event (as handled above). I can set the e.PageVisual to any visual xaml element and the PrintBitmap will handle it. Here I use the GetPages function and loop through to make sure I print each page (a pdfviewer element). However, you can point it to any visual element like I said.
Private Sub Print_Report(sender As System.Object, e As PrintPageEventArgs)
e.PageVisual = xobjReportViewer.GetPages(mintPageIndex)
mintPageIndex += 1
e.HasMorePages = mintPageIndex < xobjReportViewer.GetPages.Count
End Sub
The e.HasMorePages allows you to force the firing of this event until you are finished.
Hope this is helpful to someone. With Silverlight 5 and the Post-Script printer support, alot of printers that have a PostScript emulator may not be compatible, but will also not default to bitmap printing. This workaround fixes that, making printing a little bit more stable in a LOB type application.