I am using C# to generate a Window (scrollbar) with a lot of results: Window ResultsWindow = new Window();
At the bottom, there are two buttons, i.e. Cancel and Print. The first one does what it should. Nevertheless, the Print button should somehow convert the Window into a PDF File, or maybe one step inbetween where the user can save it afterwards.
private void Print_click(object sender, RoutedEventArgs e)
{
//add code to print the whole window??
ResultsWindow.Close();
}
Does anyone of you have an idea how this could work?
Best regards
This isn't particularly pretty (or tested) but uses information from this answer.
This creates an XPS file of your window, and converts it to PDF
using System.IO;
using System.IO.Packaging;
using System.Windows;
using System.Windows.Xps;
using System.Windows.Xps.Packaging;
namespace WpfApp8
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
/*
* Convert WPF -> XPS -> PDF
*/
MemoryStream lMemoryStream = new MemoryStream();
Package package = Package.Open(lMemoryStream, FileMode.Create);
XpsDocument doc = new XpsDocument(package);
XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(doc);
// This is your window
writer.Write(this);
doc.Close();
package.Close();
// Convert
MemoryStream outStream = new MemoryStream();
PdfSharp.Xps.XpsConverter.Convert(lMemoryStream, outStream, false);
// Write pdf file
FileStream fileStream = new FileStream("C:\\test.pdf", FileMode.Create);
outStream.CopyTo(fileStream);
// Clean up
outStream.Flush();
outStream.Close();
fileStream.Flush();
fileStream.Close();
}
}
}
It uses the PdfSharp nuget package and the kenjiuno.PdfSharp.Xps package to add XPS support to PdfSharp
Asuming you are using WPF, here is how I accomplished something similar:
private void Button_Click(object sender, RoutedEventArgs e)
{
var wasMax = this.WindowState == WindowState.Maximized;
UBlattWindow.WindowState = WindowState.Normal;
var initHeight = UBlattWindow.ActualHeight;
var initWidth = UBlattWindow.ActualWidth;
UBlattWindow.Width = 955;
UBlattWindow.Height = UBlattWindow.Height + (ScrollerContent.ActualHeight - Scroller.ActualHeight) + 20;
Print(printGrid);
UBlattWindow.Height = initHeight;
UBlattWindow.Width = initWidth;
if (wasMax)
{
UBlattWindow.WindowState = WindowState.Maximized;
}
}
private void Print(Visual v)
{
System.Windows.FrameworkElement e = v as System.Windows.FrameworkElement;
if (e == null)
return;
PrintDialog pd = new PrintDialog();
if (pd.ShowDialog() == true)
{
PageMediaSize pageSize = null;
pageSize = new PageMediaSize(PageMediaSizeName.ISOA4);
pd.PrintTicket.PageMediaSize = pageSize;
//store original scale
Transform originalScale = e.LayoutTransform;
//get selected printer capabilities
System.Printing.PrintCapabilities capabilities = pd.PrintQueue.GetPrintCapabilities(pd.PrintTicket);
//get scale of the print wrt to screen of WPF visual
double scale = Math.Min(capabilities.PageImageableArea.ExtentWidth / e.ActualWidth, capabilities.PageImageableArea.ExtentHeight /
e.ActualHeight);
//Transform the Visual to scale
e.LayoutTransform = new ScaleTransform(scale, scale);
//get the size of the printer page
System.Windows.Size sz = new System.Windows.Size(capabilities.PageImageableArea.ExtentWidth, capabilities.PageImageableArea.ExtentHeight);
//update the layout of the visual to the printer page size.
e.Measure(sz);
e.Arrange(new System.Windows.Rect(new System.Windows.Point(capabilities.PageImageableArea.OriginWidth, capabilities.PageImageableArea.OriginHeight), sz));
//now print the visual to printer to fit on the one page.
pd.PrintVisual(v, "My Print");
//apply the original transform.
e.LayoutTransform = originalScale;
}
}
Note that I use the method Print to scale the Window, so it will fit a ISOA4 format. I also set my window to a fixed width and height before the print and reset it afterwards.
Related
I haven't really written anything outside of Powershell in a long time, and I know this is ugly, but I can't seem to figure out why my new PDF is not adding the page numbers. I pulled the example from this itext kb.
I tried to make this basic app so people in the office could add the page numbers to PDF's. Here's what I have so far. It will create the new PDF (duplicate of the original), but it's not adding the page numbers.
Basically they use button1 to find their PDF via the Windows File Explorer dialog. It just stores the filename in a textbox. The second button is the "save" and should take the src file and make a copy of the src with only adding the page number at the bottom of the file (or anywhere at this point).
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using iText.Kernel.Pdf;
using iText.Layout;
using iText.Layout.Element;
using iText.Layout.Properties;
namespace PDFManipulation
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
int size = -1;
DialogResult result = openFileDialog1.ShowDialog(); // Show the dialog.
if (result == DialogResult.OK) // Test result.
{
string file = openFileDialog1.FileName;
try
{
string text = File.ReadAllText(file);
size = text.Length;
textBox1.Text = file;
}
catch (System.IO.IOException)
{
}
}
Console.WriteLine(size); // <-- Shows file size in debugging mode.
Console.WriteLine(result); // <-- For debugging use.
}
private void button2_Click(object sender, EventArgs e)
{
Stream myStream;
//SaveFileDialog saveFileDialog1 = new SaveFileDialog();
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
if ((myStream = saveFileDialog1.OpenFile()) != null)
{
// Code to write the stream goes here.
myStream.Close();
string SRC = textBox1.Text;
string DEST = saveFileDialog1.FileName;
FileInfo file = new FileInfo(DEST);
file.Directory.Create();
PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(DEST));
Document doc = new Document(pdfDoc);
int numberOfPages = pdfDoc.GetNumberOfPages();
for (int i = 1; i <= numberOfPages; i++)
{
// Write aligned text to the specified by parameters point
doc.ShowTextAligned(new Paragraph("page " + i + " of " + numberOfPages),559, 806, i, TextAlignment.CENTER, VerticalAlignment.TOP, 0);
}
doc.Close();
}
}
MessageBox.Show("PDF Page Numbering Added!", "Pages Added",MessageBoxButtons.OK);
Application.Exit();
}
}
}
I'm a dumb dumb. The x,y coordinates were off as the value 812 for the height is off the page.
that drives me nuts. I try to silent print a ribbon (1000 mm height, 150 mm width). The content is a Canvas containing a formatted Text.
If I use "Microsoft Print To PDF" it works and looks OK. When i go on and use the OKI Printer from the pdf it is fine!
If I directly try to print using the OKI, I will get a blank ribbon or (if i change some parameters) I get a very small text in the middle of nowhere.
Any ideas? Unfortunatly it is nearly impossible to Debug.
This is the print function:
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
PrintDialog prnt = new PrintDialog();
//PrintQueue queue = new LocalPrintServer().GetPrintQueue("Microsoft Print To PDF");
PrintQueue queue = new LocalPrintServer().GetPrintQueue("OKI C3450");
prnt.PrintQueue = queue;
//var f = queue.GetPrintCapabilities();
prnt.PrintTicket = new PrintTicket();
prnt.PrintTicket.PageMediaSize = new PageMediaSize(3779.53, 566.93);
prnt.PrintTicket.PageOrientation = PageOrientation.Landscape;
//if (prnt.ShowDialog() == true)
//{
Size pageSize = new Size(3779.53, 566.93);
var canvasToPrint = this.backgroundCanvasSchleife1;
this.backgroundCanvasSchleife1.Measure(pageSize);
this.backgroundCanvasSchleife1.Background = new SolidColorBrush(Colors.Transparent);
this.backgroundCanvasSchleife1.Children.RemoveRange(0, this.backgroundCanvasSchleife1.Children.Count-1);
this.backgroundCanvasSchleife1.Arrange(new Rect(0, 0, pageSize.Width, pageSize.Height));
//if (prnt.ShowDialog() == true)
//{
// try
//{
prnt.PrintVisual(this.backgroundCanvasSchleife1, "Printing Canvas");
//}catch (Exception ex)
//{
// var t = ex;
//}
//}
//}
//this.Close();
}
I have followed this link's instruction to add the Vlc.DotNet libraries (.Core, .Core.Interops, .Forms and .Wpf) to my project's solution.
I also added the 3.0.0 version of the VideoLAN.LibVLC.Windows library.
I added a vlcControl to my form and this is the resulting Designer.cs:
//
// vlcControl1
//
this.vlcControl1.BackColor = System.Drawing.Color.Black;
this.vlcControl1.Location = new System.Drawing.Point(384, 357);
this.vlcControl1.Name = "vlcControl1";
this.vlcControl1.Size = new System.Drawing.Size(75, 23);
this.vlcControl1.Spu = -1;
this.vlcControl1.TabIndex = 6;
this.vlcControl1.Text = "vlcControl1";
this.vlcControl1.VlcLibDirectory = ((System.IO.DirectoryInfo)(resources.GetObject("vlcControl1.VlcLibDirectory")));
this.vlcControl1.VlcMediaplayerOptions = null;
I've added a dummy VlcLibDirectory to the properties so I can change it later.
The path to the x86 version of my vlcLib is: E:\testLouka\dansMaCamera2.0\dansMaCamera2.0\libvlc\win-x86
I tried to use the following code to get a video feed from a RTSP stream url:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.vlcControl1 = new VlcControl()
{
Name = "vlc1",
Location = new Point(0, 0),
Dock = DockStyle.Fill,
VlcLibDirectory = new DirectoryInfo(Path.Combine("E:\\testLouka\\dansMaCamera2.0\\dansMaCamera2.0", "libvlc", IntPtr.Size == 4 ? "win-x86" : "win-x64")),
Spu = -1,
VlcMediaplayerOptions = null,
Enabled = true
};
string[] options = { ":network-caching=500" };
vlcControl1.Play(new Uri(m_stream.URL), options);
}
}
the m_stream.URL variable is returning a RTSP link looking like "rtsp://admin:admin123#190.19.191.19/Stream0"
My form shows up, but my vlcController doesn't show anything...
I looked at https://github.com/ZeBobo5/Vlc.DotNet's wiki, but I'm stuck...
What am I doing wrong here?
All you have to do is add a vlcControl to your form and add some code to its VlcLibDirectoryNeeded event.
/// <summary>
/// Looks for the vlc directory on the opening of the app
/// Opens a dialog if the libvlc folder is not found for the user to pick the good one
/// Folder for 32bits should be "libvlc\win-x86\" and "libvlc\win-x64\" for 64 bits
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void myVlcControl_VlcLibDirectoryNeeded(object sender, VlcLibDirectoryNeededEventArgs e)
{
var currentAssembly = Assembly.GetEntryAssembly();
var currentDirectory = new FileInfo(currentAssembly.Location).DirectoryName;
if (currentDirectory == null)
return;
if (IntPtr.Size == 4)
e.VlcLibDirectory = new DirectoryInfo(Path.GetFullPath(#".\libvlc\win-x86\"));
else
e.VlcLibDirectory = new DirectoryInfo(Path.GetFullPath(#".\libvlc\win-x64\"));
if (!e.VlcLibDirectory.Exists)
{
var folderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog();
folderBrowserDialog.Description = "Select Vlc libraries folder.";
folderBrowserDialog.RootFolder = Environment.SpecialFolder.Desktop;
folderBrowserDialog.ShowNewFolderButton = true;
if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
{
e.VlcLibDirectory = new DirectoryInfo(folderBrowserDialog.SelectedPath);
}
}
}
Then, you can add a play button of some sort to your form and play any wanted rtsp stream!
private void btnPlay_Click(object sender, EventArgs e)
{
myVlcControl.Play(MyStream.URL);//can test with rtsp://184.72.239.149/vod/mp4:BigBuckBunny_115k.mov
}
If the stream link is ok, you should be able to streaming it on the VLC app under Media->Open Network Stream...
I’m using WinForms. In my form I have a picturebox. On form load, my program opens an image document into my picturebox from my C:/image directory. The problem is when my program opens that image I cannot go into my C:/image directory and delete this picture because my application is using it. When I go to C:/image directory and try to delete the picture I get this error.
My goal is to have control over the image document that means i have the ability to delete the specific document even if its being used by my application.
Test: I tested if you can delete an image while viewing it at the same time with "Windows Photo Viewer" installed into in my computer, and that application lets you. Windows photo viewer doesn't lock the images. When you delete an image from the directory the image goes away in windows photo viewer as well. I want to accomplish something similar.
Suggested code: I tried implementing this but, i think i'm implementing it incorrectly.
Image img;
using (var bmpTemp = new Bitmap("image_file_path"))
{
img = new Bitmap(bmpTemp);
}
Below i provided my code i wrote to load the picture into my picture box.
private void Form1_Load(object sender, EventArgs e) //When form load you do this:
{
try // Get the tif file from C:\image\ folder
{
string path = #"C:\image\";
string[] filename = Directory.GetFiles(path, "*.tif"); //gets a specific image doc.
pictureBox1.Load(filename[0]);
lblFile.Text = filename[0];
RefreshImage(); // refreshing and showing the new file
opened = true; // the files was opened.
Image img1 = Image.FromFile(lblFile.Text);
pictureBox1.Image = img1;
pictureBox1.Width = img1.Width;
pictureBox1.Height = img1.Height;
picWidth = pictureBox1.Width;
picHeight = pictureBox1.Height;
getRatio();
}
catch (Exception ex)
{
MessageBox.Show("No files or " + ex.Message);
}
}
Make a copy of the image file bits before creating the image:
private void Form1_Load(object sender, EventArgs e) //When form load you do this:
{
try // Get the tif file from C:\image\ folder
{
string path = #"C:\image\";
string[] filename = Directory.GetFiles(path, "*.tif"); //gets a specific image doc.
FileInfo fi = new FileInfo(filename[0]);
byte [] buff = new byte[fi.Length];
using ( FileStream fs = File.OpenRead(fileToDisplay) )
{
fs.Read(buff, 0, (int)fi.Length);
}
MemoryStream ms = new MemoryStream(buff);
Bitmap img1 = new Bitmap(ms);
opened = true; // the files was opened.
pictureBox1.Image = img1;
pictureBox1.Width = img1.Width;
pictureBox1.Height = img1.Height;
picWidth = pictureBox1.Width;
picHeight = pictureBox1.Height;
getRatio();
}
catch (Exception ex)
{
MessageBox.Show("No files or " + ex.Message);
}
}
What I'm trying to do is create a Windows Journal (.jrn) file from a .txt. This conversion can be done by printing to a virtual "Journal Note Writer" printer. I've been struggling with a few different methods of getting this to work for a while now, so I've decided to try to simplify things (I hope).
What I Currently Have
Process p = new Process();
p.StartInfo = new ProcessStartInfo()
{
FileName = fileToOpen, // My .txt file I'd like to convert to a .jrn
CreateNoWindow = true,
Arguments = "-print-dialog -exit-on-print"
};
p.Start();
This opens the file in Notepad, but does not open the print dialog. I'd like for the print dialog to open and ideally to be able to specify some default options in the print dialog.
Another thing I've tried is this (found in another SO question):
Process p = new Process( );
p.StartInfo = new ProcessStartInfo( )
{
CreateNoWindow = true,
Verb = "print",
FileName = fileToOpen
};
p.Start( );
The problem with this is that it just automatically prints the file to the default printer (a physical one) without giving me the option to change it.
What I'm Looking For
At this point I'm just looking for any way to print a .txt to "Windows Note Writer." I've tried doing the printing without going through an external application, and had some trouble with that as well. I haven't been able to find any other references to converting to a .jrn file, so I'm open to ANY ideas.
To get Journal Note Writer as printer you would have to add it into the printer preferences -> Add Printer (I wonder whether it could be done programmatically).
Anyways you can always get a print of a plain .txt file as described here at MSDN.
After struggling with this issue for a while, I decided to go back to trying the handle the printing directly through the application without going through Notepad. The issue I was having before when I tried this was that changing the paper size would break the resulting .jrn file (the printout would be blank). It turns out that changing some paper size settings was necessary to print on a non-native paper size.
Below is the final code in case anybody else struggles with this issue. Thanks for everybody's help.
private void btnOpenAsJRN_Click(object sender, EventArgs e) {
string fileToOpen = this.localDownloadPath + "\\" + this.filenameToDownload;
//Create a StreamReader object
reader = new StreamReader(fileToOpen);
//Create a Verdana font with size 10
lucida10Font = new Font("Lucida Console", 10);
//Create a PrintDocument object
PrintDocument pd = new PrintDocument();
PaperSize paperSize = new PaperSize("Custom", 400, 1097);
paperSize.RawKind = (int)PaperKind.Custom;
pd.DefaultPageSettings.PaperSize = paperSize;
pd.DefaultPageSettings.Margins = new Margins(20, 20, 30, 30);
pd.PrinterSettings.PrinterName = ConfigurationManager.AppSettings["journalNotePrinter"];
pd.DocumentName = this.filenameToDownload;
//Add PrintPage event handler
pd.PrintPage += new PrintPageEventHandler(this.PrintTextFileHandler);
//Call Print Method
try {
pd.Print();
}
finally {
//Close the reader
if (reader != null) {
reader.Close();
}
this.savedJnt = fileToOpen.Replace("txt", "jnt");
System.Threading.Thread.Sleep(1000);
if (File.Exists(this.savedJnt)) {
lblJntSaved.Visible = true;
lblJntSaved.ForeColor = Color.Green;
lblJntSaved.Text = "File successfully located.";
// If the file can be found, show all of the buttons for completing
// the final steps.
lblFinalStep.Visible = true;
btnMoveToSmoketown.Visible = true;
btnEmail.Visible = true;
txbEmailAddress.Visible = true;
}
else {
lblJntSaved.Visible = true;
lblJntSaved.ForeColor = Color.Red;
lblJntSaved.Text = "File could not be located. Please check your .jnt location.";
}
}
}
private void PrintTextFileHandler(object sender, PrintPageEventArgs ppeArgs) {
//Get the Graphics object
Graphics g = ppeArgs.Graphics;
float linesPerPage = 0;
float yPos = 0;
int count = 0;
//Read margins from PrintPageEventArgs
float leftMargin = ppeArgs.MarginBounds.Left;
float topMargin = ppeArgs.MarginBounds.Top;
string line = null;
//Calculate the lines per page on the basis of the height of the page and the height of the font
linesPerPage = ppeArgs.MarginBounds.Height /
lucida10Font.GetHeight(g);
//Now read lines one by one, using StreamReader
while (count < linesPerPage &&
((line = reader.ReadLine()) != null)) {
//Calculate the starting position
yPos = topMargin + (count *
lucida10Font.GetHeight(g));
//Draw text
g.DrawString(line, lucida10Font, Brushes.Black,
leftMargin, yPos, new StringFormat());
//Move to next line
count++;
}
//If PrintPageEventArgs has more pages to print
if (line != null) {
ppeArgs.HasMorePages = true;
}
else {
ppeArgs.HasMorePages = false;
}
}