Currently I load an HTML string into a webBrowser control's contents and tell the user to print-screen it.
I'd like to somehow either grab the webBrowser contents as an image, or somehow render this HTML to an image file that can be saved. Are there any free libraries to do this?
I have been curious as to how this is accomplished myself. I have not tried to do this, but here is a link to a CodeProject article that seems to describe the process quite well:
HTML to Image in C#
I use a program called Webshot and I absolutely love it. It has a freeware version with upgrade available. It even has a callable command line interface which can be used in an automated fashion.
Link here.
Well, there's bound to be a better solution than this, but I'm pretty sure it's better than your solution (I haven't checked out the other answers), so...
I have a working C# program that saves a bitmap image of a control. Currently, the control is a textbox, but you could easily make it a web browser control. The entire program is below. The form has a button, button1, and a textbox, textBox1.
using System;
using System.Drawing;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Bitmap bm = new Bitmap(textBox1.Width,textBox1.Height);
textBox1.DrawToBitmap(bm,new Rectangle(0,0,bm.Width,bm.Height));
bm.Save("image.bmp");
}
}
}
Related
I have a pdf viewer which for the sake of the example, displays selected filename from a listbox.
It is a simple form with a listbox an axAcroPDF and textbox to confirm correct filepath.
The code is as follows and the files have been placed in a folder pdfs in the Debug folder:
using System;
using System.Windows.Forms;
namespace pdf_viewer
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
string path = AppDomain.CurrentDomain.BaseDirectory + "pdfs\\" + listBox1.SelectedItem.ToString();
textBox1.Text = path;
InitializeAdobe(path);
}
private void InitializeAdobe(string filePath)
{
axAcroPDF1.LoadFile(filePath);
axAcroPDF1.src = filePath;
axAcroPDF1.setShowToolbar(false);
axAcroPDF1.setView("Fit");
axAcroPDF1.setLayoutMode("SinglePage");
axAcroPDF1.Show();
}
}
}
It all works correctly with a few issues:
the first time you cycle through the files it displays correctly in the window but if you go back to an entry, the second time it shows the toolbar at the right despite this being disabled in the code. The toolbar takes up the bulk of the window.
When you close the window, it takes and inordinately long time to close, indicating to me there is a lot of housekeeping going on. Any clues on why this would be happening.
In addition to this:
do I need both .LoadFile and .src statements in the code as both work in isolation but is one preferable to the other. Doesn't seem to change the above issues. This method was lifted from another Stack Overflow question.
Thanks
PS Since originally posting, I have tried to display in a webBrowser window but exactly the same thing happens with the toolbar panel displaying the second time you select an entry.
The code is as follows:
webBrowser1.Url = new Uri(path);
Revisited this problem after a very long time and found the answer here
Disable Adobe Reader toolbar from my ActiveX
It appears to work in an axAcroPDF and webbrowser window.
For the axAcropdf the code to display pdf without displaying the toolbar is (using question example):
this.axAcroPDF1.src = filePath + "#toolbar=0";
this.axAcroPDF1.setView("Fit");
this.axAcroPDF1.setLayoutMode("SinglePage");
this.axAcroPDF1.Show();
For webbrowser window
InitializeAdobe(path);
webBrowser1.Url = new Uri(path + "#toolbar=0");
Let me clear the air first: yes, this is classwork. No, I don't just want the answer. I am just really stuck and looking for some assistance.
I'll be as specific as I can. I think the best way I can do that is to post the prompt the book gives:
Create a project named RecentlyVisitedSites that contains a Form with a list of three LinkLabels that link to any three Web sites you choose. When a user clicks a LinkLabel, link to that site. When a user's mouse hovers over a LinkLabel, display a brief message that explains the site's purpose. After a user clicks a link, move the most recently selected link to the top of the list, and move the other two links down, making sure to retain the correct explanation with each link.
My main problem with this is that I can't find a good way to make a "list" of the LinkLabels that both allows me to use LinkLabels in the first place and lets me rearrange items in a list-fashion. Here is my best go at it:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace RecentlyVisitedSites
{
public partial class Form1 : Form
{
LinkLabel[] links = new LinkLabel[3];
public Form1()
{
InitializeComponent();
/*LinkLabel[] links = new LinkLabel[3];
links[0] = new LinkLabel();
links[0].Text = "google.com";
links[0].Location = new System.Drawing.Point(100, 25);
links[0].Links.Add(0, 0, "www.google.com");
this.Controls.Add(links[0]);*/
LinkLabel[] links = new LinkLabel[3];
links[0] = googleLabel;
links[1] = facebookLabel;
linksPanel.Controls.Add(links[0]);
linksPanel.Controls.Add(links[1]);
}
private void googleLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
System.Diagnostics.Process.Start("IExplore", "http://www.google.com");
links[0] = googleLabel;
linksPanel.Controls.Remove(links[0]);
linksPanel.Controls.Add(links[0]);
}
private void facebookLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
System.Diagnostics.Process.Start("IExplore", "http://www.facebook.com");
links[0] = facebookLabel;
linksPanel.Controls.Remove(links[0]);
linksPanel.Controls.Add(links[0]);
}
}
}
And I always get stuck either because the links won't show up, or I can't use them the way the prompt seems to want, or some other thing. The commented-out code is something else I tried using after asking my teacher, but I didn't get much out of our conversation and it didn't work either.
What should I be doing to get these links to display on page, in a list, where I can have them be clickable, open the stated web page in a browser, and be able to rearrange them the way the prompt asks?
Again, I'm not just asking to be given an answer, I have just hit a wall and I'm frustrated because I can't seem to find a decent explanation to help me understand what I actually need to be doing. Any help would be appreciated.
Use this format for each LinkLabel on Form1:
LinkLabel.LinkVisited = true;
System.Diagnostics.Process.Start("IExplore, http://www.Facebook.com");
I have embedded an audio file (high.wav) in the resx file for my Windows Form (by just double clicking on Form1.resx in solution explorer, Ctrl+F4, then clicking 'Add Resource'), but using
Stream embeddedfile = WindowsFormsApplication2.Properties.Resources.ResourceManager.GetStream("high");
SoundPlayer sp = new SoundPlayer(embeddedfile);
sp.Play();
only plays a system sound, not the embedded one. I have tried all of the combinations of changing the Persistence from 'Linked at compile time' to 'Embedded in .resx', and Build Action from 'None' to 'Embedded Resource'. I have also tried
Stream embeddedfile = WindowsFormsApplication2.Properties.Resources.high;
which doesn't even compile, saying that 'WindowsFormsApplication2.Properties.Resources' does not contain a definition for 'high'
Sorry is this is a dumb question, I am just starting out. If it makes any difference, I am using Windows 8.1 N.
EDIT: I guess I fixed it. Apparently you cannot add resources by going (formname).cs --> (formname).resx . You must go right click the application name, go to properties, and on the sidebar thing go to resources. I don't know what the difference is, as things added the way that works shows up in the place where it doesn't work to add it.
For adding resource right click on the project name from project explorer then click on resources after add resource arrow ==> add Existing file from anyware
and this is code for playing this file added:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
using System.Media;
namespace play_Wav
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
SoundPlayer sp = new SoundPlayer(play_Wav.Properties.Resources.myFile);
sp.Play();
}
}
}
How to auto save all properties winforms when closed and auto load all properties winforms when load ? C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace SControl
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < Controls.Count; i++)
{
System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(typeof(Controls[i]));
Stream stream = File.Open("test.xml", FileMode.Create);
x.Serialize(stream, Controls[i]);
}
}
}
}
Your question is a little unclear, but
If you require saving/loading of the Form Layout have a look at
Windows Forms User Settings in C#
If you require saving/loading an object/class have a look at
Load and save objects to XML using serialization
EDIT:
This will show you how to persist certain settings for form properties.
Save and Restore Setings of a .NET Form using XML
Also have a look at The Application Automation Layer - Using XML To Dynamically Generate GUI Elements--Forms And Controls
All these will guide you in the direction you need to go.
I think the main objective here is
Figure out when to save and when to
load, and where to store/retrieve
these settings.
Are you storing these settings per
user? In a database? In a xml file?
Next you need to identify which
properties you will be
saving/restoring per control. Simple
location/size settings might not cut
it as controls will have various
complexities (Button, TextBox,
Gridview, ListView)
Now you need to figure out how to
iterate ALL controls on the form.
Buttons, Textboxes, Panels, Controls
in Controls (controls in panels), and
maybe even your User Controls. This
can be done using recursion.
Now you need to decide on the
structure of the xml file (if you opt
to use xml). This should pretty much
look like a tree structure, as you
would look at the form, and its
controls, and their controls, as a
tree structure.
I'm not aware of any automatic method built into the Form base class, but adding it yourself isn't hard.
You could tap the window load and close events to cache off all relevant properties to a backing store and then reload them later.
Register an event handler to the Form.Load and Form.Closing event handlers. When Form.Closing occurs, save the forms state to a file or database. When Form.Load occurs, check to see if a saved state is present and if so, reload the from from the saved state.
You have to manually code which properties to be saved.
A convenient method is to svae these personalized settings to Windows Forms Application Settings.
Sample code snippet:
//save the winform position and size upon closing
private void Form1_FormClosed(
object sender, FormClosedEventArgs e)
{
Properties.Settings.Default.FormPosition = this.Location;
Properties.Settings.Default.FormSize = this.Size;
Properties.Settings.Default.Save();
}
//load the winform position and size upon loading
private void Form1_Load(object sender, EventArgs e)
{
this.Size = Properties.Settings.Default.FormSize;
this.Location = Properties.Settings.Default.FormPosition;
}
More references:
Using Settings in C#
Any good examples of how to use Applications settings
Use Windows Forms Application Settings to Personalize Your Applications
The process of turning objects like forms into something that could be saved is called serialization. Unfortunately I don't think there's an out-of-box way to serialize forms in WinForm. I did find How to Clone/Serialize/Copy & Paste a Windows Forms Control, and since forms are also controls, you might be able to serialize the properties using the code.
Can I open a PDF file in RichTextBox?
Short answer: No.
Longer answer: No. A RichTextBox is for displaying rich text. PDFs can contain anything including text, but that's not the document model underlying the RichTextBox. Besides, WPF does not handle PDF natively. There are third-party controls, however.
This question also has some pointers which may be of use to you, albeit not using a RichTextBox.
You need to use the Acrobat Control for ActiveX or at least the Adobe Reader 9 equivalent and use as
using PdfLib;
namespace WindowsFormsApplication1{
public partial class ViewerForm : Form{
public ViewerForm()
{
InitializeComponent();
PdfLib.AxAcroPDF axAcroPDF1;
axAcroPDF1.LoadFile(#"C:\Documents and Settings\jcrowe\Desktop\Medical Gas\_0708170240_001.pdf");
axAcroPDF1.Show(); }
private void richTextBox1_TextChanged(object sender, EventArgs e)
{ } } }
You can write a simple app in a few seconds containing a WebBrowser control, and just call the navigate method and give it a URL pointing to the document you want.
XAML:
<Grid>
<WebBrowser x:Name="Browser"/>
</Grid>
C#:
private void Window1_Loaded(object sender, WindowLoadedArgs args)
{
Browser.Navigate(new URL("path to document.pdf");
}
Note: I am writing from memory so consider this pseudocode rather than something that will work as-is.