How to display a PDF in Winforms with no obstructions? - c#

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.

Related

What is the fastest option for printing a single page report (wpf c# program)

I am devoloping a wpf c# program that manages a school. From time to time the user has to print certifications for a single student. For instance a certification that this student is learning in our institution, or a certification with the amount of his stipend.
On these reports there is:
fixed text
dynamic information about the student like his name and so on
For this task I built rdls and it serves the purpose, but the users requested faster speed.
My question is: are rdls (working off a report server) the right method for this task? or is there a different faster option?
I use a FlowDocument for simple printing functionality such as this. You add XAML elements to the document just as you would when programmatically creating XAML in a window. Use the same layout controls (grids, stack panels, etc) to arrange all the other controls (text paragraphs, images, etc), and when the FlowDocument is printed it will be "flowed" into the page(s) based on various factors such as the paper size selected in the printer dialog.
Disclaimer: this was copy/pasted in a rush but it should give you an idea of how it works!
// Show the print dialog
var dlg = new PrintDialog();
if (!dlg.ShowDialog().GetValueOrDefault())
{
// User cancelled
return;
}
// Create and initialise the FlowDocument
_doc = new FlowDocument();
_doc.FontFamily = new FontFamily("Arial");
_doc.FontSize = 14;
// Add a paragraph of text
var para = new Paragraph(new Run("My paragraph....."))
{
FontSize = 14,
Foreground = new SolidColorBrush(Colors.Black),
Margin = new Thickness(0,0,0,12)
};
_doc.Blocks.Add(para);
// Add an image
var para = new Paragraph();
var img = new Image
{
Source = bitmapSource,
HorizontalAlignment = HorizontalAlignment.Center,
Margin = new Thickness(0,0,0,12)
};
para.Inlines.Add(img);
_doc.Blocks.Add(para);
// Print
var documentPaginator = ((IDocumentPaginatorSource)_doc).DocumentPaginator;
dlg.PrintDocument(documentPaginator, "My print job");
In my application I have all this wrapped in a class (as I have a few places where I need printing functionality). The class creates and initialises the FlowDocument in its constructor, and provides various methods such as "AddParagraph()", "AddImage()", with different overloads for specifying margins, fonts, font sizes, etc.
The document paginator bit at the end is a simplified version of my implementation, but it may be sufficient for your needs. (I've created a custom document paginator that provides the ability to set a header and footer on each page).

PDF Document does not display when creating control dynamically

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.

How do I create a copy of an asp.net chart?

I'm currently designing a web-based (asp.net/C#) volume tracking tool for a company which is used for reporting and rendering volume data. One way for the user to render data is through using a chart tool which uses the asp.net built-in chart. The user can set plenty of different filtering options to customize his chart appropriately and then have it rendered on the same page. Regarding the contents of the chart everything is working quite alright, however I have created a few controls for giving the user the possibility to generate higher quality images of their graph and show them in a separate window. Using an extension method for Response.Redirect I am redirecting the user to a new window that contains the high resolution version of the chart image, as can be seen below:
private void DownloadImage(int width, int height)
{
double scale = width / ViewGraphChart.Width.Value;
// Resize chart:
ViewGraphChart.Width = width;
ViewGraphChart.Height = height;
// Resize titles:
foreach (Title t in ViewGraphChart.Titles)
{
t.Font = new Font(t.Font.FontFamily, (float)(t.Font.Size * scale), FontStyle.Regular);
}
// Resize legends:
foreach (Legend l in ViewGraphChart.Legends)
{
l.Font = new Font(l.Font.FontFamily, (float)(l.Font.Size * scale), FontStyle.Regular);
}
UpdateChart();
// Open image in new window:
Response.Redirect(ViewGraphChart.CurrentImageLocation, "_blank", "");
}
So far so good, a new window opens up and the user is handed a high resolution version of his chart image. The problem is however that the chart in the tool also, naturally, is modified and obviously becomes way too big to properly fit inside the layout. I tried to remedy this by resetting the chart properties right after the redirect, this however made the "HD" chart image show up as the same tiny chart image inside the tool. So, I figured the best way would be to make a copy of the chart, modify the copy and hand it to the user, while the original image remains its small size within the tool. Is there any simple way to do this, considering that I have tons of databindings and other things connected to my chart, or is there some other way to go about?
I'm in somewhat of a hurry so if this came out rather unclear, please tell me and I'll explain more thoroughly.
Regards,
Ante
Edit:
The code behind the Response.Redirect extension method. Borrowed from this very page if I remember correctly.
public static void Redirect(this HttpResponse response, string url, string target, string windowFeatures)
{
if
((String.IsNullOrEmpty(target) || target.Equals("_self", StringComparison.OrdinalIgnoreCase))
&& String.IsNullOrEmpty(windowFeatures))
{
response.Redirect(url);
}
else
{
Page page = (Page)HttpContext.Current.Handler;
url = page.ResolveClientUrl(url); string script;
if (!String.IsNullOrEmpty(windowFeatures))
{
script = #"window.open(""{0}"", ""{1}"", ""{2}"");";
}
else
{
script = #"window.open(""{0}"", ""{1}"");";
}
script = String.Format(script, url, target, windowFeatures);
ScriptManager.RegisterStartupScript(page, typeof(Page), "Redirect", script, true);
}
}

how to print .htm files in c#?

I can't seem to find a good way to print .htm files in c# using .net 4.0, visual studio 2010 and windows forms. When i tried to print it directly, it printed the raw html data instead of printing the "page" itself.
The only way i know to print it, is to use a WebBrowser control. When i print the document, it doesn't print colors and the page isn't printed correctly. For example, the edges are not drawn and so on.
Code for Web Browser :
public void Print()
{
// Create a WebBrowser instance.
WebBrowser webBrowserForPrinting = new WebBrowser();
// Add an event handler that prints the document after it loads.
webBrowserForPrinting.DocumentCompleted +=
new WebBrowserDocumentCompletedEventHandler(PrintDocument);
// Set the Url property to load the document.
webBrowserForPrinting.Url = new Uri(Core.textLog);
}
private void PrintDocument(object sender, WebBrowserDocumentCompletedEventArgs e)
{
((WebBrowser)sender).ShowPrintDialog();
//// Print the document now that it is fully loaded.
//((WebBrowser)sender).Print();
//// Dispose the WebBrowser now that the task is complete.
((WebBrowser)sender).Dispose();
}
What can i do?
Thank you!
Printing web pages will forever be the bane of your existence. There just isn't a solution out there that prints HTML directly to your printer really, really well. And even if you do find a program that does it well, it's only a matter of time until you try to print a page with some unsupported formatting, in which case you're right back where you started.
What we do is print HTML to a pdf file with a program called wkhtmltopdf. Then we open it in Acrobat (which has excellent printing support) and print from there. I can't say enough good things about wkhtmltopdf. It's command line driven, and its super, super fast. Best of all, its free. It has a companion program called wkhtmltoimage that will print to most popular image formats, too (bmp, jpg, png, etc).
After downloading/installing the program, you can run a quick test by going to your command prompt, navigating to the install folder, and typing:
wkhtmltopdf "http://YouWebAddress.com" "C:/YourSaveLocation.pdf"
It also has a ton of command line switches that give you greater control over the outputs (headers, footers, page numbering, etc etc).
Ok, as i said, problem was that edge are not drawn and neither are the backgrounds.
Here is how i solved it.
Hashtable values = new Hashtable();
values.Add("margin_left", "0.1");
values.Add("margin_right", "0.1");
values.Add("margin_top", "0.1");
values.Add("margin_bottom", "0.1");
values.Add("Print_Background", "yes");
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(#"Software\Microsoft\Internet Explorer\PageSetup", true))
{
if (key == null) return;
foreach (DictionaryEntry item in values)
{
string value = (string)key.GetValue(item.Key.ToString());
if (value != item.Value.ToString())
{
key.SetValue(item.Key.ToString(), item.Value);
}
}
}
So before i print, i go to regedit, change the values, and the document gets printed perfectly. Hope this helps other people that have the same problem when printing from webbrowser control in windows forms.

modifying a print preview

I'm building a c# app that displays a print preview (of a document) and then asks the user(s) to 'sign' the document via a InkPicture control. I've got no problems extracting the Bitmap from the inkpicture control and applying it to the PrintDocument (I do this earlier in the process before the print preview and paint those images to the printdocument) but the purpose of the print preview is to allow the user(s) to review the document as it would be printed and sign off on it.
I've tried resetting the document to a modified one
// MyDocumentType derives from PrintDocument and ipSignature is a
// user control derived from InkPicture that converts the ink to
// a gif
MyDocumentType doc = (MyDocumentType)ppcPreview.Document;
doc.AddSignature(ipSignature.Gif);
ppcPreview.Document = doc;
I've tried reconstructing the print preview control
MyDocumentType doc = (MyDocumentType)ppcPreview.Document;
doc.AddSignature(ipSignature.Gif);
ppcPreview = new PrintPreviewControl();
ppcPreview.Document = doc;
to no effect.
Invalidating the control after it's modified also does nothing.
I'm kind of stumped.
Did you try using the InvalidatePreview method instead of Invalidate?

Categories