PDF Document does not display when creating control dynamically - c#

I have an application that I want to display multiple PDF documents. If I define the control at design time I can load a document and display it, but when I dynamically create the control during run time I cannot get it to display. The document is being displayed in a tab.
Here is my code...
AxAcroPDF newPDF = new AxAcroPDF();
newPDF.CreateControl();
newPDF.Width = selectedTab.Width;
newPDF.Height = selectedTab.Height;
newPDF.LoadFile(filePath);
selectedTab.Controls.Add(newPDF);
newPDF.Show();
newPDF.Visible = true;
How do I get the PDF to display?

This is what worked for me...
AxAcroPDF newPDF = new AxAcroPDF();
selectedTab.Controls.Add(newPDF);
newPDF.CreateControl();
newPDF.Width = selectedTab.Width;
newPDF.Height = selectedTab.Height;
newPDF.LoadFile(filePath);
newPDF.Show();
For some reason it doesn't like the PDF control being added to the tab after the CreateControl() method is executed.

Don't use Width and Height but ActualWidth and ActualHeight from the SelectedTab. Under certain circumstances the non actuals may report zero sizes.
Otherwise hard code height and width to see if that provides an insight as to whether it is showing up, but hidden.

Related

How to display a PDF in Winforms with no obstructions?

I want to display a PDF in my WinForms C# application. I have tried using a WebBrowser component, but it displays control bars from Adobe Reader. I have also tried a component Adobe PDF Reader control axAcroPDF, but using it crashed the responsiveness of my form, other components didn't move when resizing the form (I don't know why). What can I do to either change the WebBrowser component to not display the controls, or display the PDF in some other way?
With Magick.NET, you can convert your pdf to an image, and display it on the form. Also you need the GhostScript to be installed on your PC. Something like this:
using (var image = new MagickImage())
{
private MagickReadSettings _settings;
_settings = new MagickReadSettings()
{
FrameCount = 1, // return only one page
};
_settings.FrameIndex = 1; // return only the first page
_settings.Density = new Density(resolution); // set the resolution
image.Read(DocPath, _settings);
image.ColorAlpha(MagickColors.White);
bmp = image.ToBitmap();
}
Or, you can try this, but I have no experience with that. It is free and has some limitations, but may be it will fit your needs.

itextsharp hyperlink a image and have it open in default viewer when picked

I have a pdf file created with itextsharp with images in the file. I would like to put a hyperlink in the file that if you pick the picture it will open that picture in a picture viewer. I can set a hyperlink to a web address but have no idea how to get it to open a file. Below is the code, yes I know that c:\test.jpg is a bad hardcoded file name but it is just a test. When you click the picture it does nothing but I have no idea how to tell it what to do.
iTextSharp.text.Image pic =TextSharp.text.Image.GetInstance(comment.examplePic);
pic.ScaleToFit(200f, 200f);
Chunk cImage = new Chunk(pic, 0, 0, false);
Anchor anchor = new Anchor(cImage);
anchor.Reference = "c:\\test.jpg";
doc.Add(pic);
doc.Add(anchor);
A PDF is self-contained. This means that all the resources needed to show the PDF are (usually) stored inside the PDF (exceptions are for instance fonts that can be retrieved from the operating system).
When you have an image that is shown on a PDF page, the bytes of that image are stored in what we call an Image XObject. An XObject is an object that is external to the page, but that is stored as a separate object inside the PDF file.
You are asking to serve the image bytes stored inside this separate object to a viewer on the operating system. This is impossible. I don't know of any viewer that can take those bytes and somehow forward them to an image viewer.
I can think of three possible workarounds. I don't know if any of these workarounds is acceptable to you.
1. Serve the image online
You could put the image on a server and use the code you have in your snippet to link to that online image. Of course: this will only work if the person viewing the document is online and clicks OK when his viewer asks him if it's OK to link to a resources on the internet.
2. Serve the image as an annotation
In this case, you create an annotation for which you create an appearance that renders that same image XObject in the annotation layer (all annotations are shown on top of the page content). You can easily change the visibility status of an annotation to make it invisible (in your case, this would be the default status) or visible (in your case, this would be triggered by a JavaScript action when clicking the link).
There's an example of such an annotation here: Advertisement. If you open advertisement.pdf, you see an image with a button that says "Close this advertisement". Once you click that, the status of the annotation will be changed to invisible. You could do something similar, but the other way round: click a link to make it visible instead of invisible.
This solution doesn't depend on an external viewer, the image is shown in the PDF viewer.
3. Add the image as optional content
Starting with PDF 1.5, PDF supports optional content. See for instance the OptionalContentExample. In this example, we have some questions and answers, but the answers are not visible by default. See layer_actions.pdf. There are links "on / off / toggle" to make the answers visible or invisible.
You could do the same with images: you could add them to a layer that is invisible by default, but that can be made visible if somebody clicks a link. However: this requires a viewer that supports OCG (optional content groups) and the actions to change the status of these OCGs. For instance: if you would try the layer_actions.pdf example in the PDF viewer in Chrome, it won't work, but if you download the PDF and open it in Adobe Reader, you'll see the behavior I described.
Summarized:
You are asking something that is impossible, but there are workarounds. Please post another question if you have chosen a workaround and you don't succeed in making that workaround word (but please take into account that not all viewers support every workaround).
no offence but too much knowledge sometimes makes you ignorant of small things.
simple solution to this problem is here
http://kuujinbo.info/iTextSharp/imageAnchor.aspx
sample code that i implemented works like charm
PdfPCell p1 = new PdfPCell();
p1 = new PdfPCell();
p1.Padding = 0;
p1.Border = 0;
PdfPTable nav = new PdfPTable(1);
nav.WidthPercentage = 100;
nav.SpacingAfter = 12;
navbarImg.Annotation= new Annotation(0, 0, 0, 0, ur);
p1.Image = navbarImg;
nav.AddCell(p1);
_doc.Add(nav);

Printing Grid Control with multiple elements

I am trying to print a grid control with multiple elements in it.
I am doing this,
PrintDialog printDialog = new PrintDialog();
if (printDialog.ShowDialog() == true)
{
printDialog.PrintVisual(gridReport, "Visit Report");
}
gridReport is my grid name.
As my grid contains a lot of child elements, only a part of it is getting printed and rest is getting chopped.
How should i solve this ?
I had the same problem a month ago. As far as i know .Net print dialog only prints one page and cuts everything beyond that page. If you want to print multi pages you have to write some logic yourself.
I created a bmp file and cut it to multiple pages, added the pages to a list and at the end printed the list of pages.
I found this article very helpful (it has a solution that cuts the bmpwhenever the height of one page is exceeded, so you will also have to implement a similar logic to cut your bmp when the width of a page is exceeded)
http://www.codeproject.com/Articles/339416/Printing-large-WPF-UserControls
i hope this will help.

Scroll into a Adobe Reader using buttons c#

I Have Created a Simple form in which i have added Adobe Reader from toolbox using steps
right click in toolbox - Choose Items
choose COM Components tab and there "Adobe PDF Reader"
Now Drag&Drop the Adobe PDF Reader Control into an UserControl
I have successfully added this, opened up a pdf file also. Now it automatically provides with vertical scrollbars for scrolling through the pdf document.
What i want to achieve is instead of using the given scrollbars or mouse to scroll, i want to use a button to scroll scroll the pdf, So there will be two buttons, One for Scroll Up And the other for scroll down.
I have gone through many forums, pages, etc. Havnt found anythn that i could use.
I have Tried Simulating key presses with
SendKeys.Send("{DOWN}");
But as i press the button, the focus is lost on the adobe reader so it doesnt work
Pls help me... I have spent almost half a day searchin for a solution
given that you have provided only a simple piece of code you have tried, i am going to try offer you a generic solution - where you will need to replace the specified variables:
button names
your web app name
as for first of the focus you need to specify where it will be, something along the lines of:
var pFocus = webapplication.formname.pdf_document.focus();
// or webapplication.focus(pdf_document);
again i am just writing this as an ideal layout as i have said you will need to replace the listed variables for this to work and possibly tweak the focus code as i haven't tested that - the buttons however provided you insert your variable names will work as i have tested these:
var buttonAction = ((IJavaScriptExecutor)webapplication).ExecuteScript("window.scrollTo(0, document.body.scrollHeight - 5)");
var buttonAction_2 = ((IJavaScriptExecutor)webapplication).ExecuteScript("window.scrollTo(0, document.body.scrollHeight 0)");
//button action will scroll to x co-ordinate 0(far left), y co-ordinate( 5px from bottom)
//buttonAction_2 will return you to the very top left of page, you can edit these values to mess around and try different settings.
so altogether it should look somewhat similar to (if you are using a method for the click just insert the code under there:
var pFocus = webapplication.formname.pdf_document.focus();
if (button.click = true)
webapplication = pFocus;
var buttonAction = ((IJavaScriptExecutor)webapplication).ExecuteScript("window.scrollTo(0, document.body.scrollHeight - 5)");
pFocus.execute(buttonAction);
then for button 2
var pFocus = webapplication.formname.pdf_document.focus();
if (button_2.click = true)
webapplication = pFocus;
var buttonAction_2 = ((IJavaScriptExecutor)webapplication).ExecuteScript("window.scrollTo(0, document.body.scrollHeight 0)");
pFocus.execute(buttonAction_2);
hope this helps to some extent.

reportviewer.LocalReport.GetTotalPages() returns 0 or error

I'm using a user control, and added my report viewer and a custom toolbar. I want to create a custom navigation for it aswell, but for some reason when I want to check the total pages to decide whether or not to show the navigation buttons it either returns 0 or "This expression causes side effects and will not be evaluated" error..
I've ran out of ideas and not quite sure where to go from here..
<rsweb:reportviewer
ID="rvReports"
runat="server" ShowToolBar="False"
SizeToReportContent="True" AsyncRendering="false" />
codebehind:
rds = new Microsoft.Reporting.WebForms.ReportDataSource("dsName", myclasstoload());
rvReports.LocalReport.DataSources.Add(rds);
rvReports.PageCountMode = PageCountMode.Actual;
rvReports.LocalReport.Refresh();
rvReports.DataBind();
if (rvReports.LocalReport.GetTotalPages() > 1)
{
liFirst.Visible = true;
liPrevious.Visible = true;
liNext.Visible = true;
liLast.Visible = true;
}
this is all on the databind event in my usercontrol (.ascx). Any help is more than appreciated.
This msdn question is probably your answer, the GetTotalPages() method can't be called until after the report has rendered. The relevant quote:
The report server won't calculate the total page count until rendering the first page of the report. The ReportViewer doesn't request a page rendering from the server until the ASP.Net event PreRender. If you move the GetTotalPages call to a point after the ReportViewer.PreRender event has fired, you should get the behavior you want.
See also the ASP.NET Page Lifecycle for reference.
to get the pages as for me, I had to render the report in pdf, then using pdfreader class from Itextsharp library to get total pages
var bytes=viewer.Render("PDF");
PdfReader reader = new PdfReader(bytes);
var pageCount = reader.NumberOfPages
this works well if you want to render your rdlc in pdf format

Categories