|Visual Studio version
all browsers supported by RadControls
Demonstration on how the RadPdfViewer can be used to highlight selected text, extract the selection content, save, update and retrieve the selections for each different document. Also: add, edit, save, update, show and hide additional annotations. The annotations are shown in a "word-comments like" column on the right hand side.
- allows to select/deselect text,
- saves what's done in the protected storage (in real time), so
that the next time the same PDF is opened, it will retrieve the
- supports keyboard operations ("A" to highlight the selected text, "D" to remove the highlight),
- processes the selections so to merge or divide them in order to always have contiguous blocks,
- saves the "selected text" on the protected storage (and keeps it
in the internal objects, so that it could be used for other
functionalities within a larger application)
- Despite what happens behind the scenes it's blindingly fast: a
testimony of the good work done creating the component. Not my work,
it's the component itself that is astonishingly fast. Well done to all @Telerik.
It also supports annotations:
- Annotations are shown on a right-hand column, similar to Word comments.
- Allows to add/edit/remove annotations (double click on the column or comment)
- Comments can be moved up and down within their original page, can't cross page boundaries
- The comments column can be shown or hidden away.
- Comments are saved on an XML file (protected storage).
This started as (and still is, I'd guess) a proof-of-concept project that we needed to complete before adding this kind of functionalities in a much bigger application (EPPI-Reviewer 4, in case anyone is curious), Kammen (from Telerik) kick-started us by providing some example code in the forum. Please refer to Kammen's code in order to understand the basics of what happens behind the scenes. The RadPdfViewer component allows for massive extensions, but this is done in largely undocumented (at the time of writing) and not really obvious ways. I must add that Kammen has been very helpful in providing additional help through support tickets, so this post here is intended also as a public "thank you" for the outstanding component and support quality.
Please note that the code "as is" is not meant for production (has some known problems, see below), it also has two very different ways to provide
data persistence. Highlights are saved in a way that mimics "atomic
saves", where only the affected changes are saved onto the long term
storage (file in this case, will be a DB in our real application). The
information unit is "highlight per page" because this is how I will
eventually store it in the database.
On the other hand, annotations are associated with the PDF alone (will
sit on the same record in our DB), so they are processed in a very
different way. There is also code that transforms the old annotations
(what we have now, uses a different PDF viewer) into the new ones, and no explanation of why things work in this way is
provided. In general, in-code comments are scarce, apologies for that, I don't really have enough time to make this project easier to consume. I will try to reply to enquiries here, but only if and when time will allow, so don't expect a prompt answer.
This project uses a rudimentary kind of "self-contained" data persistence, it's good enough for demonstration purposes, but not suitable for production. In order to allow to save and retrieve data associated with different PDFs, a "mock Title" is extracted when a PDF is loaded: this is made up with the first 50 or so alphanumeric characters found in the PDF itself. It works most of the time, but it will throw an exception if no text can be found in the document (could be formed by scanned images, or use a format that RadPdfViewer can't read - see here
). Also, two different documents may have the same first 50 characters, and confuse the system in undesirable ways. I've used this solution as a quick and dirty hack for the standalone application, the real application will have each PDF associated with a unique ID so I had no need to devise a more reliable way to identify different PDFs.
note that this is all built against Silverlight 4. That's because I wanted it to use the same versions as our main application. I see no reason why it should not work on SL5, but be warned: the telerik DLL files used are compiled for SL4 (and included in the attach file for convenience). [Kammen: is that all-right? I just realised this may not be a good practice]