What are my options for printing in Silverlight 3? Assume I have this awesome Silverlight application/control that creates a graphical display of some data. Now the user wants to print it.
I have considered a few options but I have yet to test any of these. Before I do that I would like to get some feedback on how it can be done.
Use the browser printing capabilites. In my experience this is does not provide a useful print, but perhaps with some interaction between the Silverlight host and the browser it can be done?
Use WriteableBitmap. The image can either be written locally, but this requires interaction from the user, or sent to the server where a suitable file (e.g. PDF file) can be generated and then sent back to the browser. Unfortunately you now get the overhead of sending the image twice across the network and increased complexity on the server side.
Send XAML back to the server that is then rendered in a WPF application running on the server. The result is the sent back to the client. I'm not sure if this is possible at all however, but if it is the network overhead is less than in option 2. Unfortunately, the complexity on the server side is even higher.
Wait for Silverlight 4?
One thing I have considered is that my awesome control probably will have a ScrollViewer at the highest level, but the user will want to print the entire content of the control, not just whatever is visible inside the bounds of the ScrollViewer. How can I handle this added complexity?
In all seriousness, I think your best option is to wait until Silverlight 4 if your client can wait that long. I've seen a good bit of buzz about SL 4 supporting printing on twitter, though it's not official. I'd wait until PDC in a few weeks and see if any Silverlight bits trickle out to support printing.
Take a look at SmartPrint for Silverlight 3: http://www.smartwebcontrols.com/SmartPrintDetails.aspx
TBH I wouldn't use any of those options:-
Printing from the browser. Fine if you are printing say a chart or something else that scales well on a single sheet of paper. Rubbish for anything else especially where you have scrolled content.
WriteableBitmap. I can't see a client-side only solution being acceptable to the user "Please save this and then print it" message. It could be made to work bouncing off the server but would be bad for bandwidth use (bandwidth is import right? because in a well-connect intranet you wouldn't using Silverlight?).
Sending XAML to server for rendering. Really awkward it would be WPF XAML not SL XAML, where and how would you do the binding, why send XAML at all, since the server needs to be pretty much clued in on this so why can't it hold the XAML needed as well. Or were you thinking of sending just pure XAML with all the data needed? Still its a lot of plumbing needed in the SL that isn't actually related to SL.
Use Silverlight 4, its possible that in the not to distant future this would be the correct no-brainer choice (personally I wouldn't hold my breath) but right now SL4 doesn't exist.
A 5th option
Place report generating code on the server and have the Silverlight app inform the server of the data set required (not necessarily posting the data merely the criteria needed to access the correct set). In my experience direct prints of GUIs aren't particularly satisfactory when the user really needs a good printed form of the data.
Its true that at times the user just wants to quickly get some offline access to a grid of data as it looks there and then. In that situation users often find an export to spreadsheet compatible file preferable to printing, which would be possible from SL.
Something akin to number two is pretty much your best bet and is what I've seen done for printing in most Silverlight apps so far.
You can have the app send content for printing back to the web server (i.e. a new handler or query string parameters to a printing page) and pop up another page for the user to print web content from, or you could allow the user to download a file and have them print that.
Sliverlight 3 does not support printing.
If you can wait for silverlight 4, they have given it "high priority"
If not use Writeablebitmap: http://www.andybeaulieu.com/Home/tabid/67/EntryID/161/Default.aspx
Related
I've decided that RIA Services is way too limiting and am attempting to role my own server side pagination. I've long since switched over to plain old WCF. Everything is going wonderfully. My only problem, ironically, is with the front end. I'm trying to get the DataPager control to work. I could have (and it seems should have) created my own DataPager control, but I didn't want to take the time to write something as nice as the DataPager is (the control itself, not the client side query nonsense). The trouble I face, probably obviously, is setting the page count within the pager. It seems that the data pager is automagically tied to RIA services. I've tried creating an implementation of IEnumerable and IEnumerable<T> that only references a count (i.e. returns n of default(T)). I've tried using arrays of integers. All of these techniques are very wasteful and whats more, they don't work. I am to the point where it would have been much faster to write my own data pager than to use this one. So I thought I'd ask what I'm doing wrong (i.e. though I know that ultimately my wrong is in using this control without the beloved RIA client side query at all).
I figured it out. I wasn't using the PagedCollectionView.
I have recently attempted to generate reports in Silverlight 4. In my problem domain, these reports either need to go directly to the printer and/or the client-side SL application creates a PDF and allows the user to store it somewhere.
As for the report, it's roughly composed of 50% flow text (incl. enumerations), 30% tables and 20% charts. The flow text part makes it slighty more challenging, as proper line breaking would have to take place.
So far, I have tried the following approaches - each with its own shortcomings that make them not so much feasible:
Silverlight's own PrintDocument: technically, there are two major concerns. For one, getting page breaks to work and printing UIElements on it with proper layout is a bit of a dirty hackjob and full of compromises; thankfully that's the part I've managed to get working so far. However, the PrintDocument class always renders all visuals as bitmaps before sending them off; this is not so much fun, if one uses a PDF printer and hopes to still be able to search in / select text. David Poll's approach in "Silverlight and Beyond" [1] wasn't that helpful as well as it inherently follows the same approach and thus suffers from very similar issues.
silverPDF [2]: a barely documented library that requires to do most of the layout manually (the former approach at least allowed me to re-use Silverlight's layouting engine). So far, I see no way to (for instance) measure paragraphs and the only sample with long flowtext uses hardcoded absolute values for layout rectangles. Also, the developing party seems to be inactive.
Personally, I'm now thinking of following an entirely different strategy: simply generate HTML documents. But I was hoping that the community here might have hints for the two approaches above or know other good approaches.
Thanks in advance,
~Manny
Do you need to generate the report on the client, or can you get the server to generate it? Your options are better if you can generate it on the server. Personally, I think the way Silverlight printing works at the moment is pretty poor for report usage (sending each page to the printer as raster rather than vector, resulting in potentially huge amounts of data travelling through the network, and lower printing quality output). I've found the best strategy is to generate the PDF on the server (enabling you to take advantage of a reporting engine), and display it in your application. There are also a few commercial products (such as Telerik's Silverlight Report Viewer, Report Sharp Shooter, or even First Floor Software's Document Toolkit). If a client side solution is really required, perhaps one of these might be the best option (although the printing quality will still be poor). Note that Silverlight 5 is supposed to have support for vector printing, but it's another 6 months or more away from release. Yet another option is Pete Brown and David Poll's open source reporting framework here: http://silverlightreporting.codeplex.com/.
If you want to take the option of generating the report on the server as a PDF and displaying it in your application, I've written an article on doing so here: http://www.silverlightshow.net/items/Building-a-Silverlight-Line-Of-Business-Application-Part-6.aspx. This doesn't work for OOB applications, but the source code accompanying my book (Pro Business Applications with Silverlight 4) does: apress.com/book/view/9781430272076.
Hope this helps...
Chris Anderson
background
I need to be able to display charts that can capture what the user has clicked on. So for a pie chart, if a user clicks on a pie piece, I should be able to capture which piece he selected. Scatter plot should capture what plot, etc. Access-UI can't capture these things, only that a user clicked on the graph. So I need a different solution.
problem
We do not have access to a web server. The front end needs to connect directly with the access database. So what front end solutions can I use that will give me the UI flexibility I need to solve my problem?
possible solutions?
Use silverlight in access (http://desktopweb.blogspot.com/2010/12/using-silverlight-with-access-part-ii.html)
Winforms that connects to Access database via ADO
Is there anything that allows me to use HTML/JS or flash? HTML/JS would be the best solution, followed by flash just due to its wide support. I was researching Web Browser Control but I am not completely clear on whether it is opening local HTML files or browsing through http. I also wasn't clear if it supports JS or can load Flash.
When you first said about the click though capability my first thought was the reporting that is possible using SSRS. The easiest way is to have a reporting server and have the reports available through a browser. However you say you can’t have a web server so I’m guessing that a reporting server is also out.
You could however still use BIDS or report builder to make your reports and then the report viewer control in a flavour of .net to display the reports. Note that you have to convert them to RDLC files and feed the data to them.
That’s my 2p worth, I won’t comment on flash or silverlight as I don’t know enough about them to make an informed recommendation
The web browser control that's usable in Access can use any resource that can be reached via a URL, or you can assign a string of HTML (valid, of course) to it. I forget the exact property you use for the latter, but it's doable (I didn't know this the last time I implemented a web browser control to display HTML from an Access app, so created a temp file, and never went back to replace that with just assigning the HTML directly once I learned how -- so I forgot how, of course!).
In this thread from a year ago it's explained that WriteableBitmap will block read access when any part of it comes from an outside domain - say a free image server.
It's further elaborated upon that this is for "DRM". I guess there's some big threat of someone writing a movie-ripper in Silverlight that includes a movie from another domain and then re-captures it... except for the realization you can just rewrite the bloody xap as it comes down the wire and then it's same-domain! But that's neither here nor there.
Anyway, obviously I'm trying to use WritableBitmap to export a screenshot of the user's current setup; but I'm stopped by this cross-domain issue.
Is there really no supported way to do this in the latest version of Silverlight? No crossdomain.xml or clientaccesspolicy.xml? Isn't this crippling for Silverlight - a giant "Screw You", putting half-hearted security roadblocks in that impede developers but don't stop attackers?
Edit: This question is identical to this question here.
Your sentiment is shared by many, many devs trying to do this for legit purposes. There are some work-arounds out there, all of them either hacky or bizarro. But this is probably the best one I've seen: Screen Capture in SIlverlight 4.0.
Just read again and saw that you're not looking for a crossdomain.xml solution. This page has some other options (again, no solution out there is "great"): http://betaforums.silverlight.net/forums/t/118030.aspx
Also, not sure if this is an option, but your app as an OOB app will not be restricted to security checks in ClientAccessPolicy.xml or CrossDomain.xml. Is Out-of-Browser an option for you?
EDIT:
Upon further review of the post and comments, I believe (Tom, please confirm this) that the need isn't to get a screenshot of the user's instance of the SL app running on their own box (which something like Customer Support in Silverlight would take care of pretty well).
Rather, it is to take picture of the user's screen (same as PrtSc-ish). In this case, it is a lot tougher, but not impossible. Rui show's how he does it here, but it relies on a component already being on a user's machine. Jeremy get's even more creative with Silverlight 4 Hack: Use Native/Desktop CLR Without COM Registration, which would effectively allow access.
This WritableBitmap behavior have nothing to do with DRM and everything to do with security. If the screenshot you trying to take shows image element with content from different domain then that domain must have crossdomain.xml file with appropriate permissions. You can contact domain owner and ask them to place crossromain.xml in the root of their domain.
Alternatively, Full-Trust OOB application should do the trick since it doesn't check for crossdomain.xml.
Ok, If you have <Image Source="http://crossdomain.com/someimage.jpg" /> in your visual tree and you try to create WriteableBitmap from it, that WriteableBitmap's pixel access will be locked, crossdomain.xml or not. (Shame on you microsoft). Good news (sorta) is, you can use following workaround: Load image using WebClient; call SetSource on image with stream from OpenReadCompleted handler. Create your WriteableBitmap and notice how Pixels property doesn't throw security exception anymore. Far from ideal, but manageable.
As explained in the identical question the only way to get silverlight to allow you to get the content out of a Writeable Bitmap without any of the following:
Out-of-browser
Service/Code/App/Rooted GAC otherwise installed on the user's Machine
Elevated Trust
is to proxy the content and trick silverlight into thinking it's all from the same domain.
I have a very critial business application presently running using Winforms.
The application is a very core UI shell. It accepts input data, calls a webservice on my server to do the computation, displays the results on the winforms app and finally send a print stream to the printer.
Presently the application is deployed using Click-once.
Moving forward, I am trying to contemplate wheather I should move the application into a Silverlight application. Couple of reasons I am thinking silverlight.
Gives clients the feel that it is a cloud based solution.
Can be accessed from any PC. While the clickonce app is able to do this as well, they have to install an app, and when updates are available they have to click "Yes" to update.
The application presently has a drop down list of customers, this list has expanded to over 3000 records. Scrolling through the list is very painful. With Silverlight I am thinking of the auto complete ability.
Out of the browser - this will be handy for those users who use the app daily.
I haven't used Silverlight previous hence looking for some expert advice on a few things:
Printing - does silverlight allow sending raw print data to the printer. The application prints to a Zebra Thermal label printer. I have to send raw bytes to the printer with the commands. Can this be done with SL, or will it always prompt the "Print" dialog?
Out of browser - when SL apps are installed as out of browser, how to updates come through, does the app update automatically or is the user prompted to opt for update?
Printing -- using the PrintDocument API your user will be prompted for a print dialog. Currently using that API there is no way to suppress this. It isn't ideal for high-volume thermal situations (like pharmacies, shipping warehouses, etc.). You could use the trusted application mode and peek out into COM and do whatever you want with the printer.
The update happens when the application asks for it. There is an API to use and, once called, if an update exists it is downloaded -- no prompt to the user as an option. If an update is found you can alert the user to restart or that on the next restart they will have the updated application.
Autocomplete is not something that can only be done in Silverlight. Your ClickOnce app is already out-of-browser. And printing via raw bytes to a thermal printer is something that would not be easily engineered in Silverlight.
Not trying to sound negative, but in sum it sounds like you're better off simply working on enhancing the app that you already have.